summaryrefslogtreecommitdiffstats
path: root/cpukit/rtems/src/eventsurrender.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/rtems/src/eventsurrender.c')
-rw-r--r--cpukit/rtems/src/eventsurrender.c46
1 files changed, 19 insertions, 27 deletions
diff --git a/cpukit/rtems/src/eventsurrender.c b/cpukit/rtems/src/eventsurrender.c
index 05b8481a86..bfa29c425a 100644
--- a/cpukit/rtems/src/eventsurrender.c
+++ b/cpukit/rtems/src/eventsurrender.c
@@ -39,27 +39,28 @@ void _Event_Surrender(
_ISR_Disable( level );
_Event_sets_Post( event_in, &event->pending_events );
pending_events = event->pending_events;
- event_condition = the_thread->Wait.count;
-
- seized_events = _Event_sets_Get( pending_events, event_condition );
/*
- * No events were seized in this operation
+ * At this point the event condition is a speculative quantity. Later state
+ * checks will show if the thread actually waits for an event.
*/
- if ( _Event_sets_Is_empty( seized_events ) ) {
- _ISR_Enable( level );
- return;
- }
+ event_condition = the_thread->Wait.count;
- /*
- * If we are in an ISR and sending to the current thread, then
- * we have a critical section issue to deal with.
- */
- if ( _ISR_Is_in_progress() &&
- _Thread_Is_executing( the_thread ) &&
- ((*sync_state == THREAD_BLOCKING_OPERATION_TIMEOUT) ||
- (*sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED)) ) {
- if ( seized_events == event_condition || _Options_Is_any(option_set) ) {
+ seized_events = _Event_sets_Get( pending_events, event_condition );
+
+ if (
+ !_Event_sets_Is_empty( seized_events )
+ && ( seized_events == event_condition || _Options_Is_any( option_set ) )
+ ) {
+ /*
+ * If we are sending to the executing thread, then we have a critical
+ * section issue to deal with. The entity sending to the executing thread
+ * can be either the executing thread or an ISR. In case it is the
+ * executing thread, then the blocking operation state is not equal to
+ * THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED.
+ */
+ if ( _Thread_Is_executing( the_thread ) &&
+ *sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) {
event->pending_events = _Event_sets_Clear(
pending_events,
seized_events
@@ -67,16 +68,7 @@ void _Event_Surrender(
the_thread->Wait.count = 0;
*(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
*sync_state = THREAD_BLOCKING_OPERATION_SATISFIED;
- }
- _ISR_Enable( level );
- return;
- }
-
- /*
- * Otherwise, this is a normal send to another thread
- */
- if ( _States_Are_set( the_thread->current_state, wait_state ) ) {
- if ( seized_events == event_condition || _Options_Is_any( option_set ) ) {
+ } else if ( _States_Are_set( the_thread->current_state, wait_state ) ) {
event->pending_events = _Event_sets_Clear(
pending_events,
seized_events