source: rtems/cpukit/rtems/src/eventsurrender.c @ 0b422d56

4.115
Last change on this file since 0b422d56 was 0b422d56, checked in by Sebastian Huber <sebastian.huber@…>, on 01/02/13 at 17:56:36

rtems: Simplify _Event_Surrender()

It is impossible to reach the simplified expression if we are in the
THREAD_BLOCKING_OPERATION_TIMEOUT state since in this case Wait.count
(event condition) would be set to zero and thus the seized event set
would be empty.

  • Property mode set to 100644
File size: 2.8 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief Surrender Event
5 *  @ingroup ClassicEvent
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2008.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.com/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18  #include "config.h"
19#endif
20
21#include <rtems/rtems/event.h>
22
23void _Event_Surrender(
24  Thread_Control                   *the_thread,
25  rtems_event_set                   event_in,
26  Event_Control                    *event,
27  Thread_blocking_operation_States *sync_state,
28  States_Control                    wait_state
29)
30{
31  ISR_Level       level;
32  rtems_event_set pending_events;
33  rtems_event_set event_condition;
34  rtems_event_set seized_events;
35  rtems_option    option_set;
36
37  option_set = the_thread->Wait.option;
38
39  _ISR_Disable( level );
40  _Event_sets_Post( event_in, &event->pending_events );
41  pending_events  = event->pending_events;
42
43  /*
44   * At this point the event condition is a speculative quantity.  Later state
45   * checks will show if the thread actually waits for an event.
46   */
47  event_condition = the_thread->Wait.count;
48
49  seized_events = _Event_sets_Get( pending_events, event_condition );
50
51  /*
52   *  No events were seized in this operation
53   */
54  if ( _Event_sets_Is_empty( seized_events ) ) {
55    _ISR_Enable( level );
56    return;
57  }
58
59  /*
60   *  If we are in an ISR and sending to the current thread, then
61   *  we have a critical section issue to deal with.
62   */
63  if ( _ISR_Is_in_progress() &&
64       _Thread_Is_executing( the_thread ) &&
65       *sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) {
66    if ( seized_events == event_condition || _Options_Is_any(option_set) ) {
67      event->pending_events = _Event_sets_Clear(
68        pending_events,
69        seized_events
70      );
71      the_thread->Wait.count = 0;
72      *(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
73      *sync_state = THREAD_BLOCKING_OPERATION_SATISFIED;
74    }
75    _ISR_Enable( level );
76    return;
77  }
78
79  /*
80   *  Otherwise, this is a normal send to another thread
81   */
82  if ( _States_Are_set( the_thread->current_state, wait_state ) ) {
83    if ( seized_events == event_condition || _Options_Is_any( option_set ) ) {
84      event->pending_events = _Event_sets_Clear(
85        pending_events,
86        seized_events
87      );
88      the_thread->Wait.count = 0;
89      *(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
90
91      _ISR_Flash( level );
92
93      if ( !_Watchdog_Is_active( &the_thread->Timer ) ) {
94        _ISR_Enable( level );
95        _Thread_Unblock( the_thread );
96      } else {
97        _Watchdog_Deactivate( &the_thread->Timer );
98        _ISR_Enable( level );
99        (void) _Watchdog_Remove( &the_thread->Timer );
100        _Thread_Unblock( the_thread );
101      }
102      return;
103    }
104  }
105  _ISR_Enable( level );
106}
Note: See TracBrowser for help on using the repository browser.