Replaced critical section algorithm to correct race conditions.

This commit is contained in:
Joel Sherrill
1995-12-01 19:28:58 +00:00
parent 7f6fab613a
commit a8cd94aa23
2 changed files with 38 additions and 20 deletions

View File

@@ -170,13 +170,14 @@ void _Event_Seize(
return; return;
} }
_Event_Sync = TRUE; _Event_Sync = TRUE;
_Event_Sync_state = EVENT_SYNC_NOTHING_HAPPENED;
executing->Wait.option = (unsigned32) option_set; executing->Wait.option = (unsigned32) option_set;
executing->Wait.count = (unsigned32) event_in; executing->Wait.count = (unsigned32) event_in;
executing->Wait.return_argument = event_out; executing->Wait.return_argument = event_out;
_ISR_Enable( level ); _ISR_Enable( level );
_Thread_Set_state( executing, STATES_WAITING_FOR_EVENT );
if ( ticks ) { if ( ticks ) {
_Watchdog_Initialize( _Watchdog_Initialize(
@@ -188,20 +189,23 @@ void _Event_Seize(
_Watchdog_Insert_ticks( _Watchdog_Insert_ticks(
&executing->Timer, &executing->Timer,
ticks, ticks,
WATCHDOG_NO_ACTIVATE WATCHDOG_ACTIVATE_NOW
); );
} }
_Thread_Set_state( executing, STATES_WAITING_FOR_EVENT );
_ISR_Disable( level ); _ISR_Disable( level );
if ( _Event_Sync == TRUE ) { if ( _Event_Sync == TRUE ) {
_Event_Sync = FALSE; _Event_Sync = FALSE;
if ( ticks )
_Watchdog_Activate( &executing->Timer );
_ISR_Enable( level ); _ISR_Enable( level );
return; return;
} }
if ( _Event_Sync_state == EVENT_SYNC_TIMEOUT )
executing->Wait.return_code = RTEMS_TIMEOUT;
_ISR_Enable( level ); _ISR_Enable( level );
(void) _Watchdog_Remove( &executing->Timer ); if ( ticks )
(void) _Watchdog_Remove( &executing->Timer );
_Thread_Unblock( executing ); _Thread_Unblock( executing );
return; return;
} }
@@ -266,11 +270,11 @@ void _Event_Surrender(
return; return;
} }
} }
else if ( _Thread_Is_executing( the_thread ) && _Event_Sync == TRUE ) { else if ( _Event_Sync == TRUE && _Thread_Is_executing( the_thread ) ) {
if ( seized_events == event_condition || _Options_Is_any( option_set ) ) { if ( seized_events == event_condition || _Options_Is_any( option_set ) ) {
api->pending_events = _Event_sets_Clear( pending_events,seized_events ); api->pending_events = _Event_sets_Clear( pending_events,seized_events );
*(rtems_event_set *)the_thread->Wait.return_argument = seized_events; *(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
_Event_Sync = FALSE; _Event_Sync_state = EVENT_SYNC_SATISFIED;
} }
} }
} }
@@ -304,8 +308,13 @@ void _Event_Timeout(
case OBJECTS_REMOTE: /* impossible */ case OBJECTS_REMOTE: /* impossible */
break; break;
case OBJECTS_LOCAL: case OBJECTS_LOCAL:
the_thread->Wait.return_code = RTEMS_TIMEOUT; if ( _Event_Sync == TRUE && _Thread_Is_executing( the_thread ) ) {
_Thread_Unblock( the_thread ); if ( _Event_Sync_state != EVENT_SYNC_SATISFIED )
_Event_Sync_state = EVENT_SYNC_TIMEOUT;
} else {
the_thread->Wait.return_code = RTEMS_TIMEOUT;
_Thread_Unblock( the_thread );
}
_Thread_Unnest_dispatch(); _Thread_Unnest_dispatch();
break; break;
} }

View File

@@ -170,13 +170,14 @@ void _Event_Seize(
return; return;
} }
_Event_Sync = TRUE; _Event_Sync = TRUE;
_Event_Sync_state = EVENT_SYNC_NOTHING_HAPPENED;
executing->Wait.option = (unsigned32) option_set; executing->Wait.option = (unsigned32) option_set;
executing->Wait.count = (unsigned32) event_in; executing->Wait.count = (unsigned32) event_in;
executing->Wait.return_argument = event_out; executing->Wait.return_argument = event_out;
_ISR_Enable( level ); _ISR_Enable( level );
_Thread_Set_state( executing, STATES_WAITING_FOR_EVENT );
if ( ticks ) { if ( ticks ) {
_Watchdog_Initialize( _Watchdog_Initialize(
@@ -188,20 +189,23 @@ void _Event_Seize(
_Watchdog_Insert_ticks( _Watchdog_Insert_ticks(
&executing->Timer, &executing->Timer,
ticks, ticks,
WATCHDOG_NO_ACTIVATE WATCHDOG_ACTIVATE_NOW
); );
} }
_Thread_Set_state( executing, STATES_WAITING_FOR_EVENT );
_ISR_Disable( level ); _ISR_Disable( level );
if ( _Event_Sync == TRUE ) { if ( _Event_Sync == TRUE ) {
_Event_Sync = FALSE; _Event_Sync = FALSE;
if ( ticks )
_Watchdog_Activate( &executing->Timer );
_ISR_Enable( level ); _ISR_Enable( level );
return; return;
} }
if ( _Event_Sync_state == EVENT_SYNC_TIMEOUT )
executing->Wait.return_code = RTEMS_TIMEOUT;
_ISR_Enable( level ); _ISR_Enable( level );
(void) _Watchdog_Remove( &executing->Timer ); if ( ticks )
(void) _Watchdog_Remove( &executing->Timer );
_Thread_Unblock( executing ); _Thread_Unblock( executing );
return; return;
} }
@@ -266,11 +270,11 @@ void _Event_Surrender(
return; return;
} }
} }
else if ( _Thread_Is_executing( the_thread ) && _Event_Sync == TRUE ) { else if ( _Event_Sync == TRUE && _Thread_Is_executing( the_thread ) ) {
if ( seized_events == event_condition || _Options_Is_any( option_set ) ) { if ( seized_events == event_condition || _Options_Is_any( option_set ) ) {
api->pending_events = _Event_sets_Clear( pending_events,seized_events ); api->pending_events = _Event_sets_Clear( pending_events,seized_events );
*(rtems_event_set *)the_thread->Wait.return_argument = seized_events; *(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
_Event_Sync = FALSE; _Event_Sync_state = EVENT_SYNC_SATISFIED;
} }
} }
} }
@@ -304,8 +308,13 @@ void _Event_Timeout(
case OBJECTS_REMOTE: /* impossible */ case OBJECTS_REMOTE: /* impossible */
break; break;
case OBJECTS_LOCAL: case OBJECTS_LOCAL:
the_thread->Wait.return_code = RTEMS_TIMEOUT; if ( _Event_Sync == TRUE && _Thread_Is_executing( the_thread ) ) {
_Thread_Unblock( the_thread ); if ( _Event_Sync_state != EVENT_SYNC_SATISFIED )
_Event_Sync_state = EVENT_SYNC_TIMEOUT;
} else {
the_thread->Wait.return_code = RTEMS_TIMEOUT;
_Thread_Unblock( the_thread );
}
_Thread_Unnest_dispatch(); _Thread_Unnest_dispatch();
break; break;
} }