RTEMS
eventsurrender.c
Go to the documentation of this file.
1 
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.org/license/LICENSE.
15  */
16 
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20 
21 #include <rtems/rtems/eventimpl.h>
23 #include <rtems/score/threadimpl.h>
25 
26 static void _Event_Satisfy(
27  Thread_Control *the_thread,
28  Event_Control *event,
29  rtems_event_set pending_events,
30  rtems_event_set seized_events
31 )
32 {
33  event->pending_events = _Event_sets_Clear( pending_events, seized_events );
34  *(rtems_event_set *) the_thread->Wait.return_argument = seized_events;
35 }
36 
37 static bool _Event_Is_blocking_on_event(
38  const Thread_Control *the_thread,
39  Thread_Wait_flags wait_class
40 )
41 {
42  Thread_Wait_flags wait_flags;
43  Thread_Wait_flags wait_mask;
44 
45  wait_flags = _Thread_Wait_flags_get( the_thread );
47 
48  return ( wait_flags & wait_mask ) == wait_class;
49 }
50 
51 static bool _Event_Is_satisfied(
52  const Thread_Control *the_thread,
53  rtems_event_set pending_events,
54  rtems_event_set *seized_events
55 )
56 {
57  rtems_option option_set;
58  rtems_event_set event_condition;
59 
60  option_set = the_thread->Wait.option;
61  event_condition = the_thread->Wait.count;
62  *seized_events = _Event_sets_Get( pending_events, event_condition );
63 
64  return !_Event_sets_Is_empty( *seized_events )
65  && ( *seized_events == event_condition || _Options_Is_any( option_set ) );
66 }
67 
68 rtems_status_code _Event_Surrender(
69  Thread_Control *the_thread,
70  rtems_event_set event_in,
71  Event_Control *event,
72  Thread_Wait_flags wait_class,
73  ISR_lock_Context *lock_context
74 )
75 {
76  rtems_event_set pending_events;
77  rtems_event_set seized_events;
78  bool unblock;
79 
80  _Thread_Wait_acquire_default_critical( the_thread, lock_context );
81 
82  _Event_sets_Post( event_in, &event->pending_events );
83  pending_events = event->pending_events;
84 
85  if (
86  _Event_Is_blocking_on_event( the_thread, wait_class )
87  && _Event_Is_satisfied( the_thread, pending_events, &seized_events )
88  ) {
89  Thread_Wait_flags ready_again;
90  bool success;
91 
92  _Event_Satisfy( the_thread, event, pending_events, seized_events );
93 
94  ready_again = wait_class | THREAD_WAIT_STATE_READY_AGAIN;
96  the_thread,
98  ready_again
99  );
100 
101  if ( success ) {
102  unblock = false;
103  } else {
104  _Assert(
105  _Thread_Wait_flags_get( the_thread )
106  == ( wait_class | THREAD_WAIT_STATE_BLOCKED )
107  );
108  _Thread_Wait_flags_set( the_thread, ready_again );
109  unblock = true;
110  }
111  } else {
112  unblock = false;
113  }
114 
115  if ( unblock ) {
116  Per_CPU_Control *cpu_self;
117 
118  cpu_self = _Thread_Dispatch_disable_critical( lock_context );
119  _Thread_Wait_release_default( the_thread, lock_context );
120 
121  _Thread_Timer_remove( the_thread );
122  _Thread_Unblock( the_thread );
123 
124  _Thread_Dispatch_enable( cpu_self );
125  } else {
126  _Thread_Wait_release_default( the_thread, lock_context );
127  }
128 
129  return RTEMS_SUCCESSFUL;
130 }
static __inline__ void _Thread_Unblock(Thread_Control *the_thread)
Unblocks the thread.
Definition: threadimpl.h:965
Thread_Wait_information Wait
Definition: thread.h:767
Inlined Routines in the Watchdog Handler.
uint32_t rtems_option
This type is used to represent an option set.
Definition: options.h:121
RTEMS_INLINE_ROUTINE bool _Options_Is_any(rtems_option option_set)
Checks if the RTEMS_EVENT_ANY option is enabled in OPTION_SET.
Definition: optionsimpl.h:53
static __inline__ Thread_Wait_flags _Thread_Wait_flags_get(const Thread_Control *the_thread)
Gets the thread&#39;s wait flags according to the ATOMIC_ORDER_RELAXED.
Definition: threadimpl.h:2215
Classic Options Implementation.
Classic Event Manager Implementation.
This status code indicates successful completion.
Definition: status.h:86
static __inline__ Per_CPU_Control * _Thread_Dispatch_disable_critical(const ISR_lock_Context *lock_context)
Disables thread dispatching inside a critical section (interrupts disabled).
#define THREAD_WAIT_STATE_READY_AGAIN
Indicates that a condition to end the thread wait occurred.
Definition: threadimpl.h:2163
static __inline__ void _Thread_Wait_flags_set(Thread_Control *the_thread, Thread_Wait_flags flags)
Sets the thread&#39;s wait flags.
Definition: threadimpl.h:2196
rtems_status_code
This enumeration provides status codes for directives of the Classic API.
Definition: status.h:82
unsigned int Thread_Wait_flags
This type is able to contain several flags used to control the wait class and state of a thread...
Definition: thread.h:383
Per CPU Core Structure.
Definition: percpu.h:347
static __inline__ void _Thread_Timer_remove(Thread_Control *the_thread)
Remove the watchdog timer from the thread.
Definition: threadimpl.h:2456
static __inline__ rtems_event_set _Event_sets_Get(rtems_event_set the_event_set, rtems_event_set the_event_condition)
Returns the events in event_condition that are set in event_set.
Definition: eventimpl.h:113
static __inline__ bool _Thread_Wait_flags_try_change_release(Thread_Control *the_thread, Thread_Wait_flags expected_flags, Thread_Wait_flags desired_flags)
Tries to change the thread wait flags with release semantics in case of success.
Definition: threadimpl.h:2260
#define THREAD_WAIT_STATE_BLOCKED
Indicates that the thread completed the blocking operation.
Definition: threadimpl.h:2156
void _Thread_Dispatch_enable(Per_CPU_Control *cpu_self)
Enables thread dispatching.
static __inline__ rtems_event_set _Event_sets_Clear(rtems_event_set the_event_set, rtems_event_set the_mask)
Removes the events in mask from the event_set passed in.
Definition: eventimpl.h:127
static __inline__ bool _Event_sets_Is_empty(rtems_event_set the_event_set)
Checks if on events are posted in the event_set.
Definition: eventimpl.h:86
#define THREAD_WAIT_CLASS_MASK
Mask to get the thread wait class flags.
Definition: threadimpl.h:2168
Inlined Routines from the Thread Handler.
static __inline__ void _Thread_Wait_acquire_default_critical(Thread_Control *the_thread, ISR_lock_Context *lock_context)
Acquires the thread wait default lock inside a critical section (interrupts disabled).
Definition: threadimpl.h:1658
Local ISR lock context for acquire and release pairs.
Definition: isrlock.h:65
static __inline__ void _Event_sets_Post(rtems_event_set the_new_events, rtems_event_set *the_event_set)
Posts the given new_events into the event_set passed in.
Definition: eventimpl.h:99
uint32_t rtems_event_set
This integer type can hold an event set of up to 32 events represented as a bit field.
Definition: event.h:94
#define THREAD_WAIT_STATE_INTEND_TO_BLOCK
Indicates that the thread begins with the blocking operation.
Definition: threadimpl.h:2151
static __inline__ void _Thread_Wait_release_default(Thread_Control *the_thread, ISR_lock_Context *lock_context)
Releases the thread wait default lock and restores the previous interrupt status. ...
Definition: threadimpl.h:1734
#define _Assert(_e)
Assertion similar to assert() controlled via RTEMS_DEBUG instead of NDEBUG.
Definition: assert.h:100