summaryrefslogtreecommitdiffstats
path: root/cpukit/include/rtems/rtems/event.h
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/include/rtems/rtems/event.h')
-rw-r--r--cpukit/include/rtems/rtems/event.h526
1 files changed, 526 insertions, 0 deletions
diff --git a/cpukit/include/rtems/rtems/event.h b/cpukit/include/rtems/rtems/event.h
new file mode 100644
index 0000000000..1cd64c0cfa
--- /dev/null
+++ b/cpukit/include/rtems/rtems/event.h
@@ -0,0 +1,526 @@
+/**
+ * @file rtems/rtems/event.h
+ *
+ * @defgroup ClassicEvent Events
+ *
+ * @ingroup ClassicRTEMS
+ * @brief Information Related to Event Manager
+ *
+ * This include file contains the information pertaining to the Event
+ * Manager. This manager provides a high performance method of communication
+ * and synchronization.
+ *
+ * Directives provided are:
+ *
+ * - send an event set to a task
+ * - receive event condition
+ *
+ */
+
+/* COPYRIGHT (c) 1989-2008.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _RTEMS_RTEMS_EVENT_H
+#define _RTEMS_RTEMS_EVENT_H
+
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/types.h>
+#include <rtems/rtems/options.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup ClassicEventSet Event Set
+ *
+ * @ingroup ClassicEvent
+ *
+ * @{
+ */
+
+/**
+ * @brief Integer type to hold an event set of up to 32 events represented as
+ * a bit field.
+ */
+typedef uint32_t rtems_event_set;
+
+/**
+ * @brief Constant used to send or receive all events.
+ */
+#define RTEMS_ALL_EVENTS 0xFFFFFFFF
+
+/** @brief Defines the bit in the event set associated with event 0. */
+#define RTEMS_EVENT_0 0x00000001
+/** @brief Defines the bit in the event set associated with event 1. */
+#define RTEMS_EVENT_1 0x00000002
+/** @brief Defines the bit in the event set associated with event 2. */
+#define RTEMS_EVENT_2 0x00000004
+/** @brief Defines the bit in the event set associated with event 3. */
+#define RTEMS_EVENT_3 0x00000008
+/** @brief Defines the bit in the event set associated with event 4. */
+#define RTEMS_EVENT_4 0x00000010
+/** @brief Defines the bit in the event set associated with event 5. */
+#define RTEMS_EVENT_5 0x00000020
+/** @brief Defines the bit in the event set associated with event 6. */
+#define RTEMS_EVENT_6 0x00000040
+/** @brief Defines the bit in the event set associated with event 7. */
+#define RTEMS_EVENT_7 0x00000080
+/** @brief Defines the bit in the event set associated with event 8. */
+#define RTEMS_EVENT_8 0x00000100
+/** @brief Defines the bit in the event set associated with event 9. */
+#define RTEMS_EVENT_9 0x00000200
+/** @brief Defines the bit in the event set associated with event 10. */
+#define RTEMS_EVENT_10 0x00000400
+/** @brief Defines the bit in the event set associated with event 11. */
+#define RTEMS_EVENT_11 0x00000800
+/** @brief Defines the bit in the event set associated with event 12. */
+#define RTEMS_EVENT_12 0x00001000
+/** @brief Defines the bit in the event set associated with event 13. */
+#define RTEMS_EVENT_13 0x00002000
+/** @brief Defines the bit in the event set associated with event 14. */
+#define RTEMS_EVENT_14 0x00004000
+/** @brief Defines the bit in the event set associated with event 15. */
+#define RTEMS_EVENT_15 0x00008000
+/** @brief Defines the bit in the event set associated with event 16. */
+#define RTEMS_EVENT_16 0x00010000
+/** @brief Defines the bit in the event set associated with event 17. */
+#define RTEMS_EVENT_17 0x00020000
+/** @brief Defines the bit in the event set associated with event 18. */
+#define RTEMS_EVENT_18 0x00040000
+/** @brief Defines the bit in the event set associated with event 19. */
+#define RTEMS_EVENT_19 0x00080000
+/** @brief Defines the bit in the event set associated with event 20. */
+#define RTEMS_EVENT_20 0x00100000
+/** @brief Defines the bit in the event set associated with event 21. */
+#define RTEMS_EVENT_21 0x00200000
+/** @brief Defines the bit in the event set associated with event 22. */
+#define RTEMS_EVENT_22 0x00400000
+/** @brief Defines the bit in the event set associated with event 23. */
+#define RTEMS_EVENT_23 0x00800000
+/** @brief Defines the bit in the event set associated with event 24. */
+#define RTEMS_EVENT_24 0x01000000
+/** @brief Defines the bit in the event set associated with event 25. */
+#define RTEMS_EVENT_25 0x02000000
+/** @brief Defines the bit in the event set associated with event 26. */
+#define RTEMS_EVENT_26 0x04000000
+/** @brief Defines the bit in the event set associated with event 27. */
+#define RTEMS_EVENT_27 0x08000000
+/** @brief Defines the bit in the event set associated with event 29. */
+#define RTEMS_EVENT_28 0x10000000
+/** @brief Defines the bit in the event set associated with event 29. */
+#define RTEMS_EVENT_29 0x20000000
+/** @brief Defines the bit in the event set associated with event 30. */
+#define RTEMS_EVENT_30 0x40000000
+/** @brief Defines the bit in the event set associated with event 31. */
+#define RTEMS_EVENT_31 0x80000000
+
+/** @} */
+
+/**
+ * @defgroup ClassicEvent Events
+ *
+ * @ingroup ClassicRTEMS
+ *
+ * @brief The event manager provides a high performance method of intertask
+ * communication and synchronization.
+ *
+ * An event flag is used by a task (or ISR) to inform another task of the
+ * occurrence of a significant situation. Thirty-two event flags are
+ * associated with each task. A collection of one or more event flags is
+ * referred to as an event set. The data type rtems_event_set is used to
+ * manage event sets.
+ *
+ * The application developer should remember the following key characteristics
+ * of event operations when utilizing the event manager:
+ *
+ * - Events provide a simple synchronization facility.
+ * - Events are aimed at tasks.
+ * - Tasks can wait on more than one event simultaneously.
+ * - Events are independent of one another.
+ * - Events do not hold or transport data.
+ * - Events are not queued. In other words, if an event is sent more than once
+ * to a task before being received, the second and subsequent send
+ * operations to that same task have no effect.
+ *
+ * An event set is posted when it is directed (or sent) to a task. A pending
+ * event is an event that has been posted but not received. An event condition
+ * is used to specify the event set which the task desires to receive and the
+ * algorithm which will be used to determine when the request is satisfied. An
+ * event condition is satisfied based upon one of two algorithms which are
+ * selected by the user. The @ref RTEMS_EVENT_ANY algorithm states that an
+ * event condition is satisfied when at least a single requested event is
+ * posted. The @ref RTEMS_EVENT_ALL algorithm states that an event condition
+ * is satisfied when every requested event is posted.
+ *
+ * An event set or condition is built by a bitwise or of the desired events.
+ * The set of valid events is @ref RTEMS_EVENT_0 through @ref RTEMS_EVENT_31.
+ * If an event is not explicitly specified in the set or condition, then it is
+ * not present. Events are specifically designed to be mutually exclusive,
+ * therefore bitwise or and addition operations are equivalent as long as each
+ * event appears exactly once in the event set list.
+ *
+ * For example, when sending the event set consisting of @ref RTEMS_EVENT_6,
+ * @ref RTEMS_EVENT_15, and @ref RTEMS_EVENT_31, the event parameter to the
+ * rtems_event_send() directive should be @ref RTEMS_EVENT_6 |
+ * @ref RTEMS_EVENT_15 | @ref RTEMS_EVENT_31.
+ *
+ * @{
+ */
+
+/**
+ * @brief Constant used to receive the set of currently pending events in
+ * rtems_event_receive().
+ */
+#define RTEMS_PENDING_EVENTS 0
+
+/**
+ * @brief Sends an Event Set to the Target Task
+ *
+ * This directive sends an event set @a event_in to the task specified by
+ * @a id.
+ *
+ * Based upon the state of the target task, one of the following situations
+ * applies. The target task is
+ * - blocked waiting for events.
+ * If the waiting task's input event condition is
+ * - satisfied, then the task is made ready for execution.
+ * - not satisfied, then the event set is posted but left pending and the
+ * task remains blocked.
+ * - not waiting for events.
+ * - The event set is posted and left pending.
+ *
+ * Identical events sent to a task are not queued. In other words, the second,
+ * and subsequent, posting of an event to a task before it can perform an
+ * rtems_event_receive() has no effect.
+ *
+ * The calling task will be preempted if it has preemption enabled and a
+ * higher priority task is unblocked as the result of this directive.
+ *
+ * Sending an event set to a global task which does not reside on the local
+ * node will generate a request telling the remote node to send the event set
+ * to the appropriate task.
+ *
+ * @param[in] id Identifier of the target task. Specifying @ref RTEMS_SELF
+ * results in the event set being sent to the calling task.
+ * @param[in] event_in Event set sent to the target task.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INVALID_ID Invalid task identifier.
+ */
+rtems_status_code rtems_event_send (
+ rtems_id id,
+ rtems_event_set event_in
+);
+
+/**
+ * @brief Receives pending events.
+ *
+ * This directive attempts to receive the event condition specified in
+ * @a event_in. If @a event_in is set to @ref RTEMS_PENDING_EVENTS, then the
+ * current pending events are returned in @a event_out and left pending. The
+ * @ref RTEMS_WAIT and @ref RTEMS_NO_WAIT options in the @a option_set
+ * parameter are used to specify whether or not the task is willing to wait
+ * for the event condition to be satisfied. The @ref RTEMS_EVENT_ANY and @ref
+ * RTEMS_EVENT_ALL are used in the @a option_set parameter to specify whether
+ * at least a single event or the complete event set is necessary to satisfy
+ * the event condition. The @a event_out parameter is returned to the calling
+ * task with the value that corresponds to the events in @a event_in that were
+ * satisfied.
+ *
+ * A task can determine the pending event set by using a value of
+ * @ref RTEMS_PENDING_EVENTS for the input event set @a event_in. The pending
+ * events are returned to the calling task but the event set is left
+ * unaltered.
+ *
+ * A task can receive all of the currently pending events by using the a value
+ * of @ref RTEMS_ALL_EVENTS for the input event set @a event_in and
+ * @ref RTEMS_NO_WAIT | @ref RTEMS_EVENT_ANY for the option set @a option_set.
+ * The pending events are returned to the calling task and the event set is
+ * cleared. If no events are pending then the @ref RTEMS_UNSATISFIED status
+ * code will be returned.
+ *
+ * If pending events satisfy the event condition, then @a event_out is set to
+ * the satisfied events and the pending events in the event condition are
+ * cleared. If the event condition is not satisfied and @ref RTEMS_NO_WAIT is
+ * specified, then @a event_out is set to the currently satisfied events. If
+ * the calling task chooses to wait, then it will block waiting for the event
+ * condition.
+ *
+ * If the calling task must wait for the event condition to be satisfied, then
+ * the timeout parameter is used to specify the maximum interval to wait. If
+ * it is set to @ref RTEMS_NO_TIMEOUT, then the calling task will wait forever.
+ *
+ * This directive only affects the events specified in @a event_in. Any
+ * pending events that do not correspond to any of the events specified in
+ * @a event_in will be left pending.
+ *
+ * A clock tick is required to support the wait with time out functionality of
+ * this directive.
+ *
+ * @param[in] event_in Set of requested events (input events).
+ * @param[in] option_set Use a bitwise or of the following options
+ * - @ref RTEMS_WAIT - task will wait for event (default),
+ * - @ref RTEMS_NO_WAIT - task should not wait,
+ * - @ref RTEMS_EVENT_ALL - return after all events (default), and
+ * - @ref RTEMS_EVENT_ANY - return after any events.
+ * @param[in] ticks Time out in ticks. Use @ref RTEMS_NO_TIMEOUT to wait
+ * without a time out (potentially forever).
+ * @param[out] event_out Set of received events (output events).
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_UNSATISFIED Input events not satisfied (only with the
+ * @ref RTEMS_NO_WAIT option).
+ * @retval RTEMS_INVALID_ADDRESS The @a event_out pointer is @c NULL.
+ * @retval RTEMS_TIMEOUT Timed out waiting for events.
+ */
+rtems_status_code rtems_event_receive (
+ rtems_event_set event_in,
+ rtems_option option_set,
+ rtems_interval ticks,
+ rtems_event_set *event_out
+);
+
+/** @} */
+
+/**
+ * @defgroup ClassicEventSystem System Events
+ *
+ * @ingroup ClassicEvent
+ *
+ * System events are similar to normal events. They offer a second set of
+ * events. These events are intended for internal RTEMS use and should not be
+ * used by applications (with the exception of the transient system event).
+ *
+ * The event @ref RTEMS_EVENT_SYSTEM_TRANSIENT is used for transient usage.
+ * See also @ref ClassicEventTransient. This event may be used by every entity
+ * that fulfils its usage pattern.
+ */
+/**@{**/
+
+/**
+ * @brief Reserved system event for network SBWAIT usage.
+ */
+#define RTEMS_EVENT_SYSTEM_NETWORK_SBWAIT RTEMS_EVENT_24
+
+/**
+ * @brief Reserved system event for network SOSLEEP usage.
+ */
+#define RTEMS_EVENT_SYSTEM_NETWORK_SOSLEEP RTEMS_EVENT_25
+
+/**
+ * @brief Reserved system event for network socket close.
+ */
+#define RTEMS_EVENT_SYSTEM_NETWORK_CLOSE RTEMS_EVENT_26
+
+/**
+ * @brief Reserved system event to resume server threads, e.g timer or
+ * interrupt server.
+ */
+#define RTEMS_EVENT_SYSTEM_SERVER_RESUME RTEMS_EVENT_29
+
+/**
+ * @brief Reserved system event for the server threads, e.g timer or interrupt
+ * server.
+ */
+#define RTEMS_EVENT_SYSTEM_SERVER RTEMS_EVENT_30
+
+/**
+ * @brief Reserved system event for transient usage.
+ */
+#define RTEMS_EVENT_SYSTEM_TRANSIENT RTEMS_EVENT_31
+
+/**
+ * @brief See rtems_event_send().
+ */
+rtems_status_code rtems_event_system_send(
+ rtems_id id,
+ rtems_event_set event_in
+);
+
+/**
+ * @brief See rtems_event_receive().
+ */
+rtems_status_code rtems_event_system_receive(
+ rtems_event_set event_in,
+ rtems_option option_set,
+ rtems_interval ticks,
+ rtems_event_set *event_out
+);
+
+/** @} */
+
+/**
+ * @defgroup ClassicEventTransient Transient Event
+ *
+ * @ingroup ClassicEvent
+ *
+ * The transient event can be used by a client task to issue a request to
+ * another task or interrupt service (server). The server can send the
+ * transient event to the client task to notify about a request completion, see
+ * rtems_event_transient_send(). The client task can wait for the transient
+ * event reception with rtems_event_transient_receive().
+ *
+ * The user of the transient event must ensure that this event is not pending
+ * once the request is finished or cancelled. A successful reception of the
+ * transient event with rtems_event_transient_receive() will clear the
+ * transient event. If a reception with timeout is used the transient event
+ * state is undefined after a timeout return status. The transient event can
+ * be cleared unconditionally with the non-blocking
+ * rtems_event_transient_clear().
+ *
+ * @msc
+ * hscale="1.6";
+ * M [label="Main Task"], IDLE [label="Idle Task"], S [label="Server"], TIME [label="System Tick Handler"];
+ * |||;
+ * --- [label="sequence with request completion"];
+ * M box M [label="prepare request\nissue request\nrtems_event_transient_receive()"];
+ * M=>>IDLE [label="blocking operation"];
+ * IDLE=>>S [label="request completion"];
+ * S box S [label="rtems_event_transient_send()"];
+ * S=>>M [label="task is ready again"];
+ * M box M [label="finish request"];
+ * |||;
+ * --- [label="sequence with early request completion"];
+ * M box M [label="prepare request\nissue request"];
+ * M=>>S [label="request completion"];
+ * S box S [label="rtems_event_transient_send()"];
+ * S=>>M [label="transient event is now pending"];
+ * M box M [label="rtems_event_transient_receive()\nfinish request"];
+ * |||;
+ * --- [label="sequence with timeout event"];
+ * M box M [label="prepare request\nissue request\nrtems_event_transient_receive()"];
+ * M=>>IDLE [label="blocking operation"];
+ * IDLE=>>TIME [label="timeout expired"];
+ * TIME box TIME [label="cancel blocking operation"];
+ * TIME=>>M [label="task is ready again"];
+ * M box M [label="cancel request\nrtems_event_transient_clear()"];
+ * @endmsc
+ *
+ * Suppose you have a task that wants to issue a certain request and then waits
+ * for request completion. It can create a request structure and store its
+ * task identifier there. Now it can place the request on a work queue of
+ * another task (or interrupt handler). Afterwards the task waits for the
+ * reception of the transient event. Once the server task is finished with the
+ * request it can send the transient event to the waiting task and wake it up.
+ *
+ * @code
+ * #include <assert.h>
+ * #include <rtems.h>
+ *
+ * typedef struct {
+ * rtems_id task_id;
+ * bool work_done;
+ * } request;
+ *
+ * void server(rtems_task_argument arg)
+ * {
+ * rtems_status_code sc;
+ * request *req = (request *) arg;
+ *
+ * req->work_done = true;
+ *
+ * sc = rtems_event_transient_send(req->task_id);
+ * assert(sc == RTEMS_SUCCESSFUL);
+ *
+ * sc = rtems_task_delete(RTEMS_SELF);
+ * assert(sc == RTEMS_SUCCESSFUL);
+ * }
+ *
+ * void issue_request_and_wait_for_completion(void)
+ * {
+ * rtems_status_code sc;
+ * rtems_id id;
+ * request req;
+ *
+ * req.task_id = rtems_task_self();
+ * req.work_done = false;
+ *
+ * sc = rtems_task_create(
+ * rtems_build_name('S', 'E', 'R', 'V'),
+ * 1,
+ * RTEMS_MINIMUM_STACK_SIZE,
+ * RTEMS_DEFAULT_MODES,
+ * RTEMS_DEFAULT_ATTRIBUTES,
+ * &id
+ * );
+ * assert(sc == RTEMS_SUCCESSFUL);
+ *
+ * sc = rtems_task_start(id, server, (rtems_task_argument) &req);
+ * assert(sc == RTEMS_SUCCESSFUL);
+ *
+ * sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ * assert(sc == RTEMS_SUCCESSFUL);
+ *
+ * assert(req.work_done);
+ * }
+ * @endcode
+ */
+/**@{**/
+
+/**
+ * @brief See rtems_event_system_send().
+ *
+ * The system event @ref RTEMS_EVENT_SYSTEM_TRANSIENT will be sent.
+ */
+RTEMS_INLINE_ROUTINE rtems_status_code rtems_event_transient_send(
+ rtems_id id
+)
+{
+ return rtems_event_system_send( id, RTEMS_EVENT_SYSTEM_TRANSIENT );
+}
+
+/**
+ * @brief See rtems_event_system_receive().
+ *
+ * The system event @ref RTEMS_EVENT_SYSTEM_TRANSIENT will be received.
+ */
+RTEMS_INLINE_ROUTINE rtems_status_code rtems_event_transient_receive(
+ rtems_option option_set,
+ rtems_interval ticks
+)
+{
+ rtems_event_set event_out;
+
+ return rtems_event_system_receive(
+ RTEMS_EVENT_SYSTEM_TRANSIENT,
+ RTEMS_EVENT_ALL | option_set,
+ ticks,
+ &event_out
+ );
+}
+
+/**
+ * @brief See rtems_event_system_receive().
+ *
+ * The system event @ref RTEMS_EVENT_SYSTEM_TRANSIENT will be cleared.
+ */
+RTEMS_INLINE_ROUTINE void rtems_event_transient_clear( void )
+{
+ rtems_event_set event_out;
+
+ rtems_event_system_receive(
+ RTEMS_EVENT_SYSTEM_TRANSIENT,
+ RTEMS_EVENT_ALL | RTEMS_NO_WAIT,
+ 0,
+ &event_out
+ );
+}
+
+/** @} */
+
+typedef struct {
+ rtems_event_set pending_events;
+} Event_Control;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */