1 | SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause |
---|
2 | copyrights: |
---|
3 | - Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) |
---|
4 | enabled-by: true |
---|
5 | functional-type: action |
---|
6 | links: [] |
---|
7 | post-conditions: |
---|
8 | - name: SendStatus |
---|
9 | states: |
---|
10 | - name: Ok |
---|
11 | test-code: | |
---|
12 | T_rsc_success( ctx->send_status ); |
---|
13 | text: | |
---|
14 | The send event status shall be RTEMS_SUCCESSFUL. |
---|
15 | - name: InvId |
---|
16 | test-code: | |
---|
17 | T_rsc( ctx->send_status, RTEMS_INVALID_ID ); |
---|
18 | text: | |
---|
19 | The send event status shall be RTEMS_INVALID_ID. |
---|
20 | test-epilogue: null |
---|
21 | test-prologue: null |
---|
22 | - name: ReceiveStatus |
---|
23 | states: |
---|
24 | - name: None |
---|
25 | test-code: | |
---|
26 | T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNKNOWN ); |
---|
27 | T_eq_u32( GetPendingEvents( ctx ), 0 ); |
---|
28 | text: | |
---|
29 | There shall be no pending events. |
---|
30 | - name: Pending |
---|
31 | test-code: | |
---|
32 | T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNKNOWN ); |
---|
33 | T_eq_u32( GetPendingEvents( ctx ), ctx->events_to_send ); |
---|
34 | text: | |
---|
35 | All events sent shall be pending. |
---|
36 | - name: Timeout |
---|
37 | test-code: | |
---|
38 | T_rsc( ctx->receive_status, RTEMS_TIMEOUT ); |
---|
39 | T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNKNOWN ); |
---|
40 | T_eq_u32( GetPendingEvents( ctx ), ctx->events_to_send ); |
---|
41 | text: | |
---|
42 | The receive event status shall be RTEMS_TIMEOUT. All events sent after |
---|
43 | the timeout shall be pending. |
---|
44 | - name: Satisfied |
---|
45 | test-code: | |
---|
46 | T_rsc( ctx->receive_status, RTEMS_SUCCESSFUL ); |
---|
47 | |
---|
48 | if ( ctx->receive_type != RECEIVE_NORMAL ) { |
---|
49 | T_eq_int( ctx->receive_condition_state, RECEIVE_COND_SATSIFIED ); |
---|
50 | } |
---|
51 | |
---|
52 | T_eq_u32( ctx->received_events, ctx->events_to_send & INPUT_EVENTS ); |
---|
53 | T_eq_u32( GetPendingEvents( ctx ), ctx->events_to_send & ~INPUT_EVENTS ); |
---|
54 | text: | |
---|
55 | The receive event status shall be RTEMS_SUCCESSFUL. The received events |
---|
56 | shall be equal to the input events sent. The pending events shall be |
---|
57 | equal to the events sent which are not included in the input events. |
---|
58 | - name: Unsatisfied |
---|
59 | test-code: | |
---|
60 | T_rsc( ctx->receive_status, RTEMS_UNSATISFIED ); |
---|
61 | T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNKNOWN ); |
---|
62 | T_eq_u32( GetPendingEvents( ctx ), ctx->events_to_send ); |
---|
63 | text: | |
---|
64 | The receive event status shall be RTEMS_UNSATISFIED. All sent events |
---|
65 | shall be pending. |
---|
66 | - name: Blocked |
---|
67 | test-code: | |
---|
68 | T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNSATISFIED ); |
---|
69 | T_eq_u32( ctx->unsatisfied_pending, ctx->events_to_send ); |
---|
70 | text: | |
---|
71 | The receiver task shall remain blocked waiting for events after the |
---|
72 | directive call. All sent events shall be pending. |
---|
73 | test-epilogue: null |
---|
74 | test-prologue: null |
---|
75 | - name: SenderPreemption |
---|
76 | states: |
---|
77 | - name: 'No' |
---|
78 | test-code: | |
---|
79 | /* |
---|
80 | * There may be a thread switch to the runner thread if the sender thread |
---|
81 | * was on another scheduler instance. |
---|
82 | */ |
---|
83 | |
---|
84 | T_le_sz( log->recorded, 1 ); |
---|
85 | |
---|
86 | for ( i = 0; i < log->recorded; ++i ) { |
---|
87 | T_ne_u32( log->events[ i ].executing, ctx->worker_id ); |
---|
88 | T_eq_u32( log->events[ i ].heir, ctx->runner_id ); |
---|
89 | } |
---|
90 | text: | |
---|
91 | There shall be no sender preemption. |
---|
92 | - name: 'Yes' |
---|
93 | test-code: | |
---|
94 | T_eq_sz( log->recorded, 2 ); |
---|
95 | T_eq_u32( log->events[ 0 ].heir, ctx->runner_id ); |
---|
96 | T_eq_u32( log->events[ 1 ].heir, ctx->worker_id ); |
---|
97 | text: | |
---|
98 | There shall be a sender preemption. |
---|
99 | test-epilogue: null |
---|
100 | test-prologue: | |
---|
101 | T_thread_switch_log *log; |
---|
102 | size_t i; |
---|
103 | |
---|
104 | log = &ctx->thread_switch_log.log; |
---|
105 | pre-conditions: |
---|
106 | - name: Id |
---|
107 | states: |
---|
108 | - name: InvId |
---|
109 | test-code: | |
---|
110 | ctx->receiver_id = 0xffffffff; |
---|
111 | ctx->sender_type = SENDER_SELF; |
---|
112 | text: | |
---|
113 | The id parameter of the send directive shall be an invalid task object |
---|
114 | identifier. |
---|
115 | - name: Task |
---|
116 | test-code: | |
---|
117 | ctx->receiver_id = ctx->runner_id; |
---|
118 | text: | |
---|
119 | The id parameter of the send directive shall be a valid task object |
---|
120 | identifier. |
---|
121 | test-epilogue: null |
---|
122 | test-prologue: null |
---|
123 | - name: Send |
---|
124 | states: |
---|
125 | - name: Zero |
---|
126 | test-code: | |
---|
127 | ctx->events_to_send = 0; |
---|
128 | text: | |
---|
129 | The event set sent shall be the empty. |
---|
130 | - name: Unrelated |
---|
131 | test-code: | |
---|
132 | ctx->events_to_send = RTEMS_EVENT_7; |
---|
133 | text: | |
---|
134 | The event set sent shall be unrelated to the event receive condition. |
---|
135 | - name: Any |
---|
136 | test-code: | |
---|
137 | ctx->events_to_send = RTEMS_EVENT_5; |
---|
138 | text: | |
---|
139 | The event set sent shall be contain at least one but not all events of |
---|
140 | the event receive condition. |
---|
141 | - name: All |
---|
142 | test-code: | |
---|
143 | ctx->events_to_send = RTEMS_EVENT_5 | RTEMS_EVENT_23; |
---|
144 | text: | |
---|
145 | The event set sent shall be contain all events of the event receive condition. |
---|
146 | - name: MixedAny |
---|
147 | test-code: | |
---|
148 | ctx->events_to_send = RTEMS_EVENT_5 | RTEMS_EVENT_7; |
---|
149 | text: | |
---|
150 | The event set sent shall be contain at least one but not all events of |
---|
151 | the event receive condition and at least one unrelated event. |
---|
152 | - name: MixedAll |
---|
153 | test-code: | |
---|
154 | ctx->events_to_send = RTEMS_EVENT_5 | RTEMS_EVENT_7 | RTEMS_EVENT_23; |
---|
155 | text: | |
---|
156 | The event set sent shall be contain all events of the event receive |
---|
157 | condition and at least one unrelated event. |
---|
158 | test-epilogue: null |
---|
159 | test-prologue: null |
---|
160 | - name: ReceiverState |
---|
161 | states: |
---|
162 | - name: NotWaiting |
---|
163 | test-code: | |
---|
164 | ctx->sender_type = SENDER_SELF; |
---|
165 | ctx->receive_type = RECEIVE_SKIP; |
---|
166 | text: | |
---|
167 | The receiver task shall not be waiting for events. |
---|
168 | - name: Poll |
---|
169 | test-code: | |
---|
170 | ctx->sender_type = SENDER_SELF; |
---|
171 | ctx->receive_type = RECEIVE_NORMAL; |
---|
172 | ctx->receive_option_set |= RTEMS_NO_WAIT; |
---|
173 | text: | |
---|
174 | The receiver task shall poll for events. |
---|
175 | - name: Timeout |
---|
176 | test-code: | |
---|
177 | ctx->sender_type = SENDER_SELF_2; |
---|
178 | ctx->receive_type = RECEIVE_NORMAL; |
---|
179 | ctx->receive_timeout = 1; |
---|
180 | text: | |
---|
181 | The receiver task shall have waited for events with a timeout which |
---|
182 | occurred. |
---|
183 | - name: Lower |
---|
184 | test-code: | |
---|
185 | ctx->sender_type = SENDER_WORKER; |
---|
186 | ctx->sender_prio = PRIO_HIGH; |
---|
187 | ctx->receive_type = RECEIVE_NORMAL; |
---|
188 | text: | |
---|
189 | The receiver task shall be blocked waiting for events and the receiver |
---|
190 | task shall have a lower priority than the sender task. |
---|
191 | - name: Equal |
---|
192 | test-code: | |
---|
193 | ctx->sender_type = SENDER_WORKER; |
---|
194 | ctx->sender_prio = PRIO_NORMAL; |
---|
195 | ctx->receive_type = RECEIVE_NORMAL; |
---|
196 | text: | |
---|
197 | The receiver task shall be blocked waiting for events and the receiver |
---|
198 | task shall have a priority equal to the sender task. |
---|
199 | - name: Higher |
---|
200 | test-code: | |
---|
201 | ctx->sender_type = SENDER_WORKER; |
---|
202 | ctx->sender_prio = PRIO_LOW; |
---|
203 | ctx->receive_type = RECEIVE_NORMAL; |
---|
204 | text: | |
---|
205 | The receiver task shall be blocked waiting for events and the receiver |
---|
206 | task shall have a higher priority than the sender task. |
---|
207 | - name: Other |
---|
208 | test-code: | |
---|
209 | ctx->sender_type = SENDER_WORKER; |
---|
210 | ctx->sender_prio = PRIO_OTHER; |
---|
211 | ctx->receive_type = RECEIVE_NORMAL; |
---|
212 | text: | |
---|
213 | The receiver task shall be blocked waiting for events and the receiver |
---|
214 | task shall be on another scheduler instance than the sender task. |
---|
215 | - name: Intend |
---|
216 | test-code: | |
---|
217 | ctx->sender_type = SENDER_INTERRUPT; |
---|
218 | ctx->receive_type = RECEIVE_INTERRUPT; |
---|
219 | text: | |
---|
220 | The receiver task shall intend to block for waiting for events. |
---|
221 | test-epilogue: null |
---|
222 | test-prologue: null |
---|
223 | - name: Satisfy |
---|
224 | states: |
---|
225 | - name: All |
---|
226 | test-code: | |
---|
227 | ctx->receive_option_set |= RTEMS_EVENT_ALL; |
---|
228 | text: | |
---|
229 | The receiver task shall be interested in all input events. |
---|
230 | - name: Any |
---|
231 | test-code: | |
---|
232 | ctx->receive_option_set |= RTEMS_EVENT_ANY; |
---|
233 | text: | |
---|
234 | The receiver task shall be interested in any input event. |
---|
235 | test-epilogue: null |
---|
236 | test-prologue: null |
---|
237 | rationale: null |
---|
238 | references: [] |
---|
239 | requirement-type: functional |
---|
240 | skip-reasons: |
---|
241 | NoOtherScheduler: | |
---|
242 | In non-SMP configurations, there exists exactly one scheduler instance. |
---|
243 | test-action: | |
---|
244 | if ( ctx->sender_type == SENDER_SELF ) { |
---|
245 | SendAction( ctx ); |
---|
246 | } else if ( ctx->sender_type == SENDER_WORKER ) { |
---|
247 | Wakeup( ctx->worker_wakeup ); |
---|
248 | } |
---|
249 | |
---|
250 | if ( ctx->receive_type == RECEIVE_NORMAL ) { |
---|
251 | ctx->receive_status = ( *ctx->receive )( |
---|
252 | INPUT_EVENTS, |
---|
253 | ctx->receive_option_set, |
---|
254 | ctx->receive_timeout, |
---|
255 | &ctx->received_events |
---|
256 | ); |
---|
257 | } else if ( ctx->receive_type == RECEIVE_INTERRUPT ) { |
---|
258 | T_interrupt_test_state state; |
---|
259 | |
---|
260 | state = T_interrupt_test( &InterruptConfig, ctx ); |
---|
261 | T_eq_int( state, T_INTERRUPT_TEST_DONE ); |
---|
262 | } |
---|
263 | |
---|
264 | if ( ctx->sender_type == SENDER_SELF_2 ) { |
---|
265 | SendAction( ctx ); |
---|
266 | } else if ( ctx->sender_type == SENDER_WORKER ) { |
---|
267 | rtems_status_code sc; |
---|
268 | rtems_task_priority prio; |
---|
269 | |
---|
270 | Wait( ctx->runner_wakeup ); |
---|
271 | |
---|
272 | prio = 0; |
---|
273 | sc = rtems_task_set_priority( ctx->worker_id, PRIO_LOW, &prio ); |
---|
274 | T_rsc_success( sc ); |
---|
275 | T_eq_u32( prio, PRIO_HIGH ); |
---|
276 | } |
---|
277 | test-brief: null |
---|
278 | test-cleanup: | |
---|
279 | rtems_status_code sc; |
---|
280 | rtems_event_set events; |
---|
281 | |
---|
282 | events = 0; |
---|
283 | sc = ( *ctx->receive )( |
---|
284 | RTEMS_ALL_EVENTS, |
---|
285 | RTEMS_NO_WAIT | RTEMS_EVENT_ANY, |
---|
286 | 0, |
---|
287 | &events |
---|
288 | ); |
---|
289 | if ( sc == RTEMS_SUCCESSFUL ) { |
---|
290 | T_quiet_ne_u32( events, 0 ); |
---|
291 | } else { |
---|
292 | T_quiet_rsc( sc, RTEMS_UNSATISFIED ); |
---|
293 | T_quiet_eq_u32( events, 0 ); |
---|
294 | } |
---|
295 | test-context: |
---|
296 | - brief: | |
---|
297 | This member defines the sender type to perform the event send action. |
---|
298 | description: null |
---|
299 | member: SenderTypes sender_type |
---|
300 | - brief: | |
---|
301 | This member defines the sender task priority. |
---|
302 | description: null |
---|
303 | member: Priorities sender_prio |
---|
304 | - brief: | |
---|
305 | This member defines the receiver ID used for the event send action. |
---|
306 | description: null |
---|
307 | member: rtems_id receiver_id |
---|
308 | - brief: | |
---|
309 | This member defines the events to send for the event send action. |
---|
310 | description: null |
---|
311 | member: rtems_event_set events_to_send |
---|
312 | - brief: | |
---|
313 | This member contains the status of the event send action. |
---|
314 | description: null |
---|
315 | member: rtems_status_code send_status |
---|
316 | - brief: | |
---|
317 | This member contains the scheduler ID of the runner task. |
---|
318 | description: null |
---|
319 | member: ReceiveTypes receive_type |
---|
320 | - brief: | |
---|
321 | This member defines the option set used for the event receive action. |
---|
322 | description: null |
---|
323 | member: rtems_option receive_option_set |
---|
324 | - brief: | |
---|
325 | This member defines the timeout used for the event receive action. |
---|
326 | description: null |
---|
327 | member: rtems_interval receive_timeout |
---|
328 | - brief: | |
---|
329 | This member contains the events received by the event receive action. |
---|
330 | description: null |
---|
331 | member: rtems_event_set received_events |
---|
332 | - brief: | |
---|
333 | This member contains the status of the event receive action. |
---|
334 | description: null |
---|
335 | member: rtems_status_code receive_status |
---|
336 | - brief: | |
---|
337 | This member contains the event conditon state of the receiver task after |
---|
338 | the event send action. |
---|
339 | description: null |
---|
340 | member: ReceiveConditionStates receive_condition_state |
---|
341 | - brief: | |
---|
342 | This member contains the pending events after an event send action which |
---|
343 | did not satsify the event condition of the receiver. |
---|
344 | description: null |
---|
345 | member: rtems_event_set unsatisfied_pending |
---|
346 | - brief: | |
---|
347 | This member contains the TCB of the runner task. |
---|
348 | description: null |
---|
349 | member: Thread_Control *runner_thread |
---|
350 | - brief: | |
---|
351 | This member contains the ID of the runner task. |
---|
352 | description: null |
---|
353 | member: rtems_id runner_id |
---|
354 | - brief: | |
---|
355 | This member contains the task ID of the worker task. |
---|
356 | description: null |
---|
357 | member: rtems_id worker_id |
---|
358 | - brief: | |
---|
359 | This member contains the ID of the semaphore used to wake up the worker |
---|
360 | task. |
---|
361 | description: null |
---|
362 | member: rtems_id worker_wakeup |
---|
363 | - brief: | |
---|
364 | This member contains the ID of the semaphore used to wake up the runner |
---|
365 | task. |
---|
366 | description: null |
---|
367 | member: rtems_id runner_wakeup |
---|
368 | - brief: | |
---|
369 | This member contains the scheduler ID of scheduler used by the runner task. |
---|
370 | description: null |
---|
371 | member: rtems_id runner_sched |
---|
372 | - brief: | |
---|
373 | This member contains the scheduler ID of another scheduler which is not |
---|
374 | used by the runner task. |
---|
375 | description: null |
---|
376 | member: rtems_id other_sched |
---|
377 | - brief: | |
---|
378 | This member contains the thread switch log. |
---|
379 | description: null |
---|
380 | member: T_thread_switch_log_4 thread_switch_log |
---|
381 | test-context-support: | |
---|
382 | typedef enum { |
---|
383 | PRIO_HIGH = 1, |
---|
384 | PRIO_NORMAL, |
---|
385 | PRIO_LOW, |
---|
386 | PRIO_OTHER |
---|
387 | } Priorities; |
---|
388 | |
---|
389 | typedef enum { |
---|
390 | SENDER_NONE, |
---|
391 | SENDER_SELF, |
---|
392 | SENDER_SELF_2, |
---|
393 | SENDER_WORKER, |
---|
394 | SENDER_INTERRUPT |
---|
395 | } SenderTypes; |
---|
396 | |
---|
397 | typedef enum { |
---|
398 | RECEIVE_SKIP, |
---|
399 | RECEIVE_NORMAL, |
---|
400 | RECEIVE_INTERRUPT |
---|
401 | } ReceiveTypes; |
---|
402 | |
---|
403 | typedef enum { |
---|
404 | RECEIVE_COND_UNKNOWN, |
---|
405 | RECEIVE_COND_SATSIFIED, |
---|
406 | RECEIVE_COND_UNSATISFIED |
---|
407 | } ReceiveConditionStates; |
---|
408 | test-description: null |
---|
409 | test-header: |
---|
410 | code: null |
---|
411 | includes: |
---|
412 | - rtems.h |
---|
413 | - rtems/score/thread.h |
---|
414 | local-includes: [] |
---|
415 | run-params: |
---|
416 | - description: | |
---|
417 | is the event send handler. |
---|
418 | dir: null |
---|
419 | name: send |
---|
420 | specifier: rtems_status_code ( *${.:name} )( rtems_id, rtems_event_set ) |
---|
421 | - description: | |
---|
422 | is the event receive handler. |
---|
423 | dir: null |
---|
424 | name: receive |
---|
425 | specifier: | |
---|
426 | rtems_status_code ( *${.:name} )( rtems_event_set, rtems_option, rtems_interval, rtems_event_set * ) |
---|
427 | - description: | |
---|
428 | is the get pending events handler. |
---|
429 | dir: null |
---|
430 | name: get_pending_events |
---|
431 | specifier: rtems_event_set ( *${.:name} )( Thread_Control * ) |
---|
432 | - description: | |
---|
433 | is the thread wait class. |
---|
434 | dir: null |
---|
435 | name: wait_class |
---|
436 | specifier: unsigned int ${.:name} |
---|
437 | - description: | |
---|
438 | is the thread waiting for event state. |
---|
439 | dir: null |
---|
440 | name: waiting_for_event |
---|
441 | specifier: int ${.:name} |
---|
442 | target: testsuites/validation/tr-event-send-receive.h |
---|
443 | test-includes: |
---|
444 | - rtems/score/threadimpl.h |
---|
445 | test-local-includes: |
---|
446 | - tr-event-send-receive.h |
---|
447 | test-prepare: | |
---|
448 | ctx->events_to_send = 0; |
---|
449 | ctx->send_status = RTEMS_INCORRECT_STATE; |
---|
450 | ctx->received_events = 0xffffffff; |
---|
451 | ctx->receive_option_set = 0; |
---|
452 | ctx->receive_timeout = RTEMS_NO_TIMEOUT; |
---|
453 | ctx->sender_type = SENDER_NONE; |
---|
454 | ctx->sender_prio = PRIO_NORMAL; |
---|
455 | ctx->receive_type = RECEIVE_SKIP; |
---|
456 | ctx->receive_condition_state = RECEIVE_COND_UNKNOWN; |
---|
457 | ctx->unsatisfied_pending = 0xffffffff; |
---|
458 | memset( &ctx->thread_switch_log, 0, sizeof( ctx->thread_switch_log ) ); |
---|
459 | T_eq_u32( GetPendingEvents( ctx ), 0 ); |
---|
460 | _Thread_Wait_flags_set( ctx->runner_thread, THREAD_WAIT_FLAGS_INITIAL ); |
---|
461 | test-setup: |
---|
462 | brief: null |
---|
463 | code: | |
---|
464 | static char task_stack[ RTEMS_MINIMUM_STACK_SIZE ]; |
---|
465 | static const rtems_task_config task_config = { |
---|
466 | .name = rtems_build_name( 'W', 'O', 'R', 'K' ), |
---|
467 | .initial_priority = PRIO_LOW, |
---|
468 | .stack_area = task_stack, |
---|
469 | .stack_size = sizeof( task_stack ), |
---|
470 | .initial_modes = RTEMS_DEFAULT_MODES, |
---|
471 | .attribute_set = RTEMS_DEFAULT_ATTRIBUTES |
---|
472 | }; |
---|
473 | |
---|
474 | rtems_status_code sc; |
---|
475 | rtems_task_priority prio; |
---|
476 | |
---|
477 | memset( ctx, 0, sizeof( *ctx ) ); |
---|
478 | ctx->runner_thread = _Thread_Get_executing(); |
---|
479 | ctx->runner_id = ctx->runner_thread->Object.id; |
---|
480 | ctx->worker_wakeup = CreateWakeupSema(); |
---|
481 | ctx->runner_wakeup = CreateWakeupSema(); |
---|
482 | |
---|
483 | sc = rtems_task_get_scheduler( RTEMS_SELF, &ctx->runner_sched ); |
---|
484 | T_rsc_success( sc ); |
---|
485 | |
---|
486 | #if defined(RTEMS_SMP) |
---|
487 | sc = rtems_scheduler_ident_by_processor( 1, &ctx->other_sched ); |
---|
488 | T_rsc_success( sc ); |
---|
489 | T_ne_u32( ctx->runner_sched, ctx->other_sched ); |
---|
490 | #endif |
---|
491 | |
---|
492 | prio = 0; |
---|
493 | sc = rtems_task_set_priority( RTEMS_SELF, PRIO_NORMAL, &prio ); |
---|
494 | T_rsc_success( sc ); |
---|
495 | T_eq_u32( prio, PRIO_HIGH ); |
---|
496 | |
---|
497 | sc = rtems_task_build( &task_config, &ctx->worker_id ); |
---|
498 | T_assert_rsc_success( sc ); |
---|
499 | |
---|
500 | sc = rtems_task_start( ctx->worker_id, Worker, (rtems_task_argument) ctx ); |
---|
501 | T_assert_rsc_success( sc ); |
---|
502 | description: null |
---|
503 | test-stop: null |
---|
504 | test-support: | |
---|
505 | #define INPUT_EVENTS ( RTEMS_EVENT_5 | RTEMS_EVENT_23 ) |
---|
506 | |
---|
507 | typedef ReqRtemsEventSendReceive_Context Context; |
---|
508 | |
---|
509 | static rtems_id CreateWakeupSema( void ) |
---|
510 | { |
---|
511 | rtems_status_code sc; |
---|
512 | rtems_id id; |
---|
513 | |
---|
514 | sc = rtems_semaphore_create( |
---|
515 | rtems_build_name( 'W', 'K', 'U', 'P' ), |
---|
516 | 0, |
---|
517 | RTEMS_SIMPLE_BINARY_SEMAPHORE, |
---|
518 | 0, |
---|
519 | &id |
---|
520 | ); |
---|
521 | T_assert_rsc_success( sc ); |
---|
522 | |
---|
523 | return id; |
---|
524 | } |
---|
525 | |
---|
526 | static void DeleteWakeupSema( rtems_id id ) |
---|
527 | { |
---|
528 | if ( id != 0 ) { |
---|
529 | rtems_status_code sc; |
---|
530 | |
---|
531 | sc = rtems_semaphore_delete( id ); |
---|
532 | T_rsc_success( sc ); |
---|
533 | } |
---|
534 | } |
---|
535 | |
---|
536 | static void Wait( rtems_id id ) |
---|
537 | { |
---|
538 | rtems_status_code sc; |
---|
539 | |
---|
540 | sc = rtems_semaphore_obtain( id, RTEMS_WAIT, RTEMS_NO_TIMEOUT ); |
---|
541 | T_quiet_rsc_success( sc ); |
---|
542 | } |
---|
543 | |
---|
544 | static void Wakeup( rtems_id id ) |
---|
545 | { |
---|
546 | rtems_status_code sc; |
---|
547 | |
---|
548 | sc = rtems_semaphore_release( id ); |
---|
549 | T_quiet_rsc_success( sc ); |
---|
550 | } |
---|
551 | |
---|
552 | static bool BlockedForEvent( Context *ctx, Thread_Wait_flags flags ) |
---|
553 | { |
---|
554 | return flags == ( ctx->wait_class | THREAD_WAIT_STATE_BLOCKED ); |
---|
555 | } |
---|
556 | |
---|
557 | static bool IntendsToBlockForEvent( Context *ctx, Thread_Wait_flags flags ) |
---|
558 | { |
---|
559 | return flags == ( ctx->wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK ); |
---|
560 | } |
---|
561 | |
---|
562 | static bool EventReadyAgain( Context *ctx, Thread_Wait_flags flags ) |
---|
563 | { |
---|
564 | return flags == ( ctx->wait_class | THREAD_WAIT_STATE_READY_AGAIN ); |
---|
565 | } |
---|
566 | |
---|
567 | static bool IsSatisfiedFlags( Context *ctx ) |
---|
568 | { |
---|
569 | return EventReadyAgain( |
---|
570 | ctx, |
---|
571 | _Thread_Wait_flags_get( ctx->runner_thread ) |
---|
572 | ); |
---|
573 | } |
---|
574 | |
---|
575 | static bool IsSatisfiedState( Context *ctx ) |
---|
576 | { |
---|
577 | return ctx->runner_thread->current_state != ctx->waiting_for_event; |
---|
578 | } |
---|
579 | |
---|
580 | static void SendAction( Context *ctx ) |
---|
581 | { |
---|
582 | T_thread_switch_log *log; |
---|
583 | |
---|
584 | log = T_thread_switch_record_4( &ctx->thread_switch_log ); |
---|
585 | T_quiet_null( log ); |
---|
586 | ctx->send_status = ( *ctx->send )( ctx->receiver_id, ctx->events_to_send ); |
---|
587 | log = T_thread_switch_record( NULL ); |
---|
588 | T_quiet_eq_ptr( log, &ctx->thread_switch_log.log ); |
---|
589 | } |
---|
590 | |
---|
591 | static void Send( |
---|
592 | Context *ctx, |
---|
593 | bool ( *is_satsified )( Context * ) |
---|
594 | ) |
---|
595 | { |
---|
596 | SendAction( ctx ); |
---|
597 | |
---|
598 | if ( ( *is_satsified )( ctx ) ) { |
---|
599 | ctx->receive_condition_state = RECEIVE_COND_SATSIFIED; |
---|
600 | } else { |
---|
601 | rtems_status_code sc; |
---|
602 | rtems_event_set pending; |
---|
603 | rtems_event_set missing; |
---|
604 | |
---|
605 | ctx->receive_condition_state = RECEIVE_COND_UNSATISFIED; |
---|
606 | pending = ( *ctx->get_pending_events )( ctx->runner_thread ); |
---|
607 | ctx->unsatisfied_pending = pending; |
---|
608 | |
---|
609 | missing = INPUT_EVENTS & ~ctx->events_to_send; |
---|
610 | T_ne_u32( missing, 0 ); |
---|
611 | sc = ( *ctx->send )( ctx->runner_id, missing ); |
---|
612 | T_rsc_success( sc ); |
---|
613 | |
---|
614 | pending = ( *ctx->get_pending_events )( ctx->runner_thread ); |
---|
615 | T_eq_u32( pending, ctx->events_to_send & ~INPUT_EVENTS ); |
---|
616 | } |
---|
617 | } |
---|
618 | |
---|
619 | static void Worker( rtems_task_argument arg ) |
---|
620 | { |
---|
621 | Context *ctx; |
---|
622 | |
---|
623 | ctx = (Context *) arg; |
---|
624 | |
---|
625 | while ( true ) { |
---|
626 | rtems_status_code sc; |
---|
627 | rtems_task_priority prio; |
---|
628 | |
---|
629 | Wait( ctx->worker_wakeup ); |
---|
630 | |
---|
631 | switch ( ctx->sender_prio ) { |
---|
632 | case PRIO_NORMAL: |
---|
633 | case PRIO_HIGH: |
---|
634 | prio = 0; |
---|
635 | sc = rtems_task_set_priority( RTEMS_SELF, ctx->sender_prio, &prio ); |
---|
636 | T_rsc_success( sc ); |
---|
637 | T_eq_u32( prio, PRIO_LOW ); |
---|
638 | break; |
---|
639 | case PRIO_OTHER: |
---|
640 | sc = rtems_task_set_scheduler( |
---|
641 | RTEMS_SELF, |
---|
642 | ctx->other_sched, |
---|
643 | PRIO_LOW |
---|
644 | ); |
---|
645 | T_rsc_success( sc ); |
---|
646 | break; |
---|
647 | case PRIO_LOW: |
---|
648 | break; |
---|
649 | } |
---|
650 | |
---|
651 | Send( ctx, IsSatisfiedState ); |
---|
652 | |
---|
653 | sc = rtems_task_set_scheduler( |
---|
654 | RTEMS_SELF, |
---|
655 | ctx->runner_sched, |
---|
656 | PRIO_HIGH |
---|
657 | ); |
---|
658 | T_rsc_success( sc ); |
---|
659 | |
---|
660 | Wakeup( ctx->runner_wakeup ); |
---|
661 | } |
---|
662 | } |
---|
663 | |
---|
664 | static rtems_event_set GetPendingEvents( Context *ctx ) |
---|
665 | { |
---|
666 | rtems_event_set pending; |
---|
667 | rtems_status_code sc; |
---|
668 | |
---|
669 | sc = ( *ctx->receive )( |
---|
670 | RTEMS_PENDING_EVENTS, |
---|
671 | RTEMS_DEFAULT_OPTIONS, |
---|
672 | 0, |
---|
673 | &pending |
---|
674 | ); |
---|
675 | T_quiet_rsc_success( sc ); |
---|
676 | |
---|
677 | return pending; |
---|
678 | } |
---|
679 | |
---|
680 | static void ReqRtemsEventSendReceive_Cleanup( Context *ctx ); |
---|
681 | |
---|
682 | static void InterruptPrepare( void *arg ) |
---|
683 | { |
---|
684 | ReqRtemsEventSendReceive_Cleanup( arg ); |
---|
685 | } |
---|
686 | |
---|
687 | static void InterruptAction( void *arg ) |
---|
688 | { |
---|
689 | Context *ctx; |
---|
690 | |
---|
691 | ctx = arg; |
---|
692 | ctx->receive_status = ( *ctx->receive )( |
---|
693 | INPUT_EVENTS, |
---|
694 | ctx->receive_option_set, |
---|
695 | ctx->receive_timeout, |
---|
696 | &ctx->received_events |
---|
697 | ); |
---|
698 | T_quiet_rsc_success( ctx->receive_status ); |
---|
699 | } |
---|
700 | |
---|
701 | static void InterruptContinue( Context *ctx ) |
---|
702 | { |
---|
703 | rtems_status_code sc; |
---|
704 | |
---|
705 | sc = ( *ctx->send )( ctx->receiver_id, INPUT_EVENTS ); |
---|
706 | T_quiet_rsc_success( sc ); |
---|
707 | } |
---|
708 | |
---|
709 | static T_interrupt_test_state Interrupt( void *arg ) |
---|
710 | { |
---|
711 | Context *ctx; |
---|
712 | Thread_Wait_flags flags; |
---|
713 | T_interrupt_test_state next_state; |
---|
714 | T_interrupt_test_state previous_state; |
---|
715 | |
---|
716 | ctx = arg; |
---|
717 | flags = _Thread_Wait_flags_get( ctx->runner_thread ); |
---|
718 | |
---|
719 | if ( IntendsToBlockForEvent( ctx, flags ) ) { |
---|
720 | next_state = T_INTERRUPT_TEST_DONE; |
---|
721 | } else if ( BlockedForEvent( ctx, flags ) ) { |
---|
722 | next_state = T_INTERRUPT_TEST_LATE; |
---|
723 | } else { |
---|
724 | next_state = T_INTERRUPT_TEST_EARLY; |
---|
725 | } |
---|
726 | |
---|
727 | previous_state = T_interrupt_test_change_state( |
---|
728 | T_INTERRUPT_TEST_ACTION, |
---|
729 | next_state |
---|
730 | ); |
---|
731 | |
---|
732 | if ( previous_state == T_INTERRUPT_TEST_ACTION ) { |
---|
733 | if ( next_state == T_INTERRUPT_TEST_DONE ) { |
---|
734 | Send( ctx, IsSatisfiedFlags ); |
---|
735 | } else { |
---|
736 | InterruptContinue( ctx ); |
---|
737 | } |
---|
738 | } |
---|
739 | |
---|
740 | return next_state; |
---|
741 | } |
---|
742 | |
---|
743 | static const T_interrupt_test_config InterruptConfig = { |
---|
744 | .prepare = InterruptPrepare, |
---|
745 | .action = InterruptAction, |
---|
746 | .interrupt = Interrupt, |
---|
747 | .max_iteration_count = 10000 |
---|
748 | }; |
---|
749 | test-target: testsuites/validation/tr-event-send-receive.c |
---|
750 | test-teardown: |
---|
751 | brief: null |
---|
752 | code: | |
---|
753 | rtems_status_code sc; |
---|
754 | rtems_task_priority prio; |
---|
755 | |
---|
756 | prio = 0; |
---|
757 | sc = rtems_task_set_priority( RTEMS_SELF, PRIO_HIGH, &prio ); |
---|
758 | T_rsc_success( sc ); |
---|
759 | T_eq_u32( prio, PRIO_NORMAL ); |
---|
760 | |
---|
761 | if ( ctx->worker_id != 0 ) { |
---|
762 | sc = rtems_task_delete( ctx->worker_id ); |
---|
763 | T_rsc_success( sc ); |
---|
764 | } |
---|
765 | |
---|
766 | DeleteWakeupSema( ctx->worker_wakeup ); |
---|
767 | DeleteWakeupSema( ctx->runner_wakeup ); |
---|
768 | description: null |
---|
769 | text: ${.:text-template} |
---|
770 | transition-map: |
---|
771 | - enabled-by: true |
---|
772 | post-conditions: |
---|
773 | ReceiveStatus: None |
---|
774 | SendStatus: InvId |
---|
775 | SenderPreemption: 'No' |
---|
776 | pre-conditions: |
---|
777 | Id: |
---|
778 | - InvId |
---|
779 | ReceiverState: N/A |
---|
780 | Satisfy: N/A |
---|
781 | Send: N/A |
---|
782 | - enabled-by: true |
---|
783 | post-conditions: |
---|
784 | ReceiveStatus: Pending |
---|
785 | SendStatus: Ok |
---|
786 | SenderPreemption: 'No' |
---|
787 | pre-conditions: |
---|
788 | Id: |
---|
789 | - Task |
---|
790 | ReceiverState: |
---|
791 | - NotWaiting |
---|
792 | Satisfy: N/A |
---|
793 | Send: all |
---|
794 | - enabled-by: true |
---|
795 | post-conditions: |
---|
796 | ReceiveStatus: Timeout |
---|
797 | SendStatus: Ok |
---|
798 | SenderPreemption: 'No' |
---|
799 | pre-conditions: |
---|
800 | Id: |
---|
801 | - Task |
---|
802 | ReceiverState: |
---|
803 | - Timeout |
---|
804 | Satisfy: all |
---|
805 | Send: all |
---|
806 | - enabled-by: true |
---|
807 | post-conditions: |
---|
808 | ReceiveStatus: Unsatisfied |
---|
809 | SendStatus: Ok |
---|
810 | SenderPreemption: 'No' |
---|
811 | pre-conditions: |
---|
812 | Id: |
---|
813 | - Task |
---|
814 | ReceiverState: |
---|
815 | - Poll |
---|
816 | Satisfy: all |
---|
817 | Send: |
---|
818 | - Zero |
---|
819 | - Unrelated |
---|
820 | - enabled-by: true |
---|
821 | post-conditions: |
---|
822 | ReceiveStatus: Blocked |
---|
823 | SendStatus: Ok |
---|
824 | SenderPreemption: 'No' |
---|
825 | pre-conditions: |
---|
826 | Id: |
---|
827 | - Task |
---|
828 | ReceiverState: |
---|
829 | - Lower |
---|
830 | - Equal |
---|
831 | - Higher |
---|
832 | - Intend |
---|
833 | Satisfy: all |
---|
834 | Send: |
---|
835 | - Unrelated |
---|
836 | - Zero |
---|
837 | - enabled-by: true |
---|
838 | post-conditions: |
---|
839 | ReceiveStatus: Satisfied |
---|
840 | SendStatus: Ok |
---|
841 | SenderPreemption: 'Yes' |
---|
842 | pre-conditions: |
---|
843 | Id: |
---|
844 | - Task |
---|
845 | ReceiverState: |
---|
846 | - Higher |
---|
847 | Satisfy: all |
---|
848 | Send: |
---|
849 | - All |
---|
850 | - MixedAll |
---|
851 | - enabled-by: true |
---|
852 | post-conditions: |
---|
853 | ReceiveStatus: Satisfied |
---|
854 | SendStatus: Ok |
---|
855 | SenderPreemption: 'No' |
---|
856 | pre-conditions: |
---|
857 | Id: |
---|
858 | - Task |
---|
859 | ReceiverState: |
---|
860 | - Poll |
---|
861 | - Lower |
---|
862 | - Equal |
---|
863 | - Intend |
---|
864 | Satisfy: all |
---|
865 | Send: |
---|
866 | - All |
---|
867 | - MixedAll |
---|
868 | - enabled-by: true |
---|
869 | post-conditions: |
---|
870 | ReceiveStatus: Satisfied |
---|
871 | SendStatus: Ok |
---|
872 | SenderPreemption: 'Yes' |
---|
873 | pre-conditions: |
---|
874 | Id: |
---|
875 | - Task |
---|
876 | ReceiverState: |
---|
877 | - Higher |
---|
878 | Satisfy: |
---|
879 | - Any |
---|
880 | Send: |
---|
881 | - Any |
---|
882 | - MixedAny |
---|
883 | - enabled-by: true |
---|
884 | post-conditions: |
---|
885 | ReceiveStatus: Satisfied |
---|
886 | SendStatus: Ok |
---|
887 | SenderPreemption: 'No' |
---|
888 | pre-conditions: |
---|
889 | Id: |
---|
890 | - Task |
---|
891 | ReceiverState: |
---|
892 | - Poll |
---|
893 | - Lower |
---|
894 | - Equal |
---|
895 | - Intend |
---|
896 | Satisfy: |
---|
897 | - Any |
---|
898 | Send: |
---|
899 | - Any |
---|
900 | - MixedAny |
---|
901 | - enabled-by: true |
---|
902 | post-conditions: |
---|
903 | ReceiveStatus: Unsatisfied |
---|
904 | SendStatus: Ok |
---|
905 | SenderPreemption: 'No' |
---|
906 | pre-conditions: |
---|
907 | Id: |
---|
908 | - Task |
---|
909 | ReceiverState: |
---|
910 | - Poll |
---|
911 | Satisfy: |
---|
912 | - All |
---|
913 | Send: |
---|
914 | - Any |
---|
915 | - MixedAny |
---|
916 | - enabled-by: true |
---|
917 | post-conditions: |
---|
918 | ReceiveStatus: Blocked |
---|
919 | SendStatus: Ok |
---|
920 | SenderPreemption: 'No' |
---|
921 | pre-conditions: |
---|
922 | Id: |
---|
923 | - Task |
---|
924 | ReceiverState: |
---|
925 | - Lower |
---|
926 | - Equal |
---|
927 | - Higher |
---|
928 | - Intend |
---|
929 | Satisfy: |
---|
930 | - All |
---|
931 | Send: |
---|
932 | - Any |
---|
933 | - MixedAny |
---|
934 | - enabled-by: true |
---|
935 | post-conditions: NoOtherScheduler |
---|
936 | pre-conditions: |
---|
937 | Id: |
---|
938 | - Task |
---|
939 | ReceiverState: |
---|
940 | - Other |
---|
941 | Satisfy: all |
---|
942 | Send: all |
---|
943 | - enabled-by: RTEMS_SMP |
---|
944 | post-conditions: |
---|
945 | ReceiveStatus: Blocked |
---|
946 | SendStatus: Ok |
---|
947 | SenderPreemption: 'No' |
---|
948 | pre-conditions: |
---|
949 | Id: |
---|
950 | - Task |
---|
951 | ReceiverState: |
---|
952 | - Other |
---|
953 | Satisfy: all |
---|
954 | Send: |
---|
955 | - Unrelated |
---|
956 | - Zero |
---|
957 | - enabled-by: RTEMS_SMP |
---|
958 | post-conditions: |
---|
959 | ReceiveStatus: Satisfied |
---|
960 | SendStatus: Ok |
---|
961 | SenderPreemption: 'No' |
---|
962 | pre-conditions: |
---|
963 | Id: |
---|
964 | - Task |
---|
965 | ReceiverState: |
---|
966 | - Other |
---|
967 | Satisfy: all |
---|
968 | Send: |
---|
969 | - All |
---|
970 | - MixedAll |
---|
971 | - enabled-by: RTEMS_SMP |
---|
972 | post-conditions: |
---|
973 | ReceiveStatus: Satisfied |
---|
974 | SendStatus: Ok |
---|
975 | SenderPreemption: 'No' |
---|
976 | pre-conditions: |
---|
977 | Id: |
---|
978 | - Task |
---|
979 | ReceiverState: |
---|
980 | - Other |
---|
981 | Satisfy: |
---|
982 | - Any |
---|
983 | Send: |
---|
984 | - Any |
---|
985 | - MixedAny |
---|
986 | - enabled-by: RTEMS_SMP |
---|
987 | post-conditions: |
---|
988 | ReceiveStatus: Blocked |
---|
989 | SendStatus: Ok |
---|
990 | SenderPreemption: 'No' |
---|
991 | pre-conditions: |
---|
992 | Id: |
---|
993 | - Task |
---|
994 | ReceiverState: |
---|
995 | - Other |
---|
996 | Satisfy: |
---|
997 | - All |
---|
998 | Send: |
---|
999 | - Any |
---|
1000 | - MixedAny |
---|
1001 | type: requirement |
---|