/* * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of ARM nor the names of its contributors may be used * to endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef __EVENTS_H__ #define __EVENTS_H__ #include typedef struct { /* * Counter that keeps track of the minimum number of recipients of the * event. When the event is sent, this counter is incremented. When it * is received, it is decremented. Therefore, a zero value means that * the event hasn't been sent yet, or that all recipients have already * received it. * * Volatile is needed as it will enforce ordering relatively to * accesses to the lock. */ volatile unsigned int cnt; /* Lock used to avoid concurrent accesses to the counter */ spinlock_t lock; } event_t; /* * Initialise an event. * event: Address of the event to initialise * * This function can be used either to initialise a newly created event * structure or to recycle one. * * Note: This function is not MP-safe. It can't use the event lock as it is * responsible for initialising it. Care must be taken to ensure this function * is called in the right circumstances. */ void tftf_init_event(event_t *event); /* * Send an event to a CPU. * event: Address of the variable that acts as a synchronisation object. * * Which CPU receives the event is determined on a first-come, first-served * basis. If several CPUs are waiting for the same event then the first CPU * which takes the event will reflect that in the event structure. * * Note: This is equivalent to calling: * tftf_send_event_to(event, 1); */ void tftf_send_event(event_t *event); /* * Send an event to all CPUs. * event: Address of the variable that acts as a synchronisation object. * * Note: This is equivalent to calling: * tftf_send_event_to(event, PLATFORM_CORE_COUNT); */ void tftf_send_event_to_all(event_t *event); /* * Send an event to a given number of CPUs. * event: Address of the variable that acts as a synchronisation object. * cpus_count: Number of CPUs to send the event to. * * Which CPUs receive the event is determined on a first-come, first-served * basis. If more than 'cpus_count' CPUs are waiting for the same event then the * first 'cpus_count' CPUs which take the event will reflect that in the event * structure. */ void tftf_send_event_to(event_t *event, unsigned int cpus_count); /* * Wait for an event. * event: Address of the variable that acts as a synchronisation object. */ void tftf_wait_for_event(event_t *event); #endif /* __EVENTS_H__ */