summaryrefslogtreecommitdiffstats
path: root/cpukit/rtems/include/rtems/rtems/event.h
blob: 381b328de29626a858a04ea7770bde9d2664105c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/**
 * @file rtems/rtems/event.h
 *
 *  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.com/license/LICENSE.
 */

#ifndef _RTEMS_RTEMS_EVENT_H
#define _RTEMS_RTEMS_EVENT_H

/**
 *  This constant is defined to extern most of the time when using
 *  this header file.  However by defining it to nothing, the data
 *  declared in this header file can be instantiated.  This is done
 *  in a single per manager file.
 */
#ifndef RTEMS_EVENT_EXTERN
#define RTEMS_EVENT_EXTERN extern
#endif

#ifdef __cplusplus
extern "C" {
#endif

#include <rtems/score/object.h>
#include <rtems/rtems/status.h>
#include <rtems/rtems/types.h>
#include <rtems/rtems/options.h>
#include <rtems/score/thread.h>
#include <rtems/score/threadsync.h>
#include <rtems/score/watchdog.h>
#include <rtems/rtems/eventset.h>

/**
 *  @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 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
 *  @aref RTEMS_WAIT and @aref 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 ScoreEvent Event Handler
 *
 *  @ingroup Score
 *
 *  @{
 */

typedef struct {
  rtems_event_set pending_events;
} Event_Control;

/**
 *  This constant is passed as the event_in to the
 *  rtems_event_receive directive to determine which events are pending.
 */
#define EVENT_CURRENT  0

void _Event_Manager_initialization( void );

void _Event_Seize(
  rtems_event_set                   event_in,
  rtems_option                      option_set,
  rtems_interval                    ticks,
  rtems_event_set                  *event_out,
  Thread_Control                   *executing,
  Event_Control                    *event,
  Thread_blocking_operation_States *sync_state,
  States_Control                    wait_state
);

void _Event_Surrender(
  Thread_Control                   *the_thread,
  rtems_event_set                   event_in,
  Event_Control                    *event,
  Thread_blocking_operation_States *sync_state,
  States_Control                    wait_state
);

void _Event_Timeout(
  Objects_Id  id,
  void       *ignored
);

RTEMS_EVENT_EXTERN Thread_blocking_operation_States _Event_Sync_state;

/** @} */

#if defined(RTEMS_MULTIPROCESSING)
#include <rtems/rtems/eventmp.h>
#endif
#ifndef __RTEMS_APPLICATION__
#include <rtems/rtems/event.inl>
#endif

#ifdef __cplusplus
}
#endif

#endif
/* end of include file */