diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2015-03-04 08:02:19 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2015-03-05 11:36:45 +0100 |
commit | 7d6e94b12ab94f13d3e769702d50f91be7d5884b (patch) | |
tree | 2e2db2c1bb80c1f287f2c4c25f819ffa8b958704 /cpukit/rtems/src/eventseize.c | |
parent | score: Add thread wait flags (diff) | |
download | rtems-7d6e94b12ab94f13d3e769702d50f91be7d5884b.tar.bz2 |
score: Implement fine-grained locking for events
Use the ISR lock of the thread object to protect the event state and
use the Giant lock only for the blocking operations.
Update #2273.
Diffstat (limited to 'cpukit/rtems/src/eventseize.c')
-rw-r--r-- | cpukit/rtems/src/eventseize.c | 77 |
1 files changed, 39 insertions, 38 deletions
diff --git a/cpukit/rtems/src/eventseize.c b/cpukit/rtems/src/eventseize.c index ca7c111ab0..59a2b6256f 100644 --- a/cpukit/rtems/src/eventseize.c +++ b/cpukit/rtems/src/eventseize.c @@ -31,24 +31,25 @@ */ void _Event_Seize( - rtems_event_set event_in, - rtems_option option_set, - rtems_interval ticks, - rtems_event_set *event_out, - Thread_Control *executing, - Event_Control *event, - Thread_blocking_operation_States *sync_state, - States_Control wait_state + rtems_event_set event_in, + rtems_option option_set, + rtems_interval ticks, + rtems_event_set *event_out, + Thread_Control *executing, + Event_Control *event, + Thread_Wait_flags wait_class, + States_Control block_state, + ISR_lock_Context *lock_context ) { - rtems_event_set seized_events; - rtems_event_set pending_events; - ISR_Level level; - Thread_blocking_operation_States current_sync_state; + rtems_event_set seized_events; + rtems_event_set pending_events; + bool success; + Thread_Wait_flags intend_to_block; + Per_CPU_Control *cpu_self; executing->Wait.return_code = RTEMS_SUCCESSFUL; - _ISR_Disable( level ); pending_events = event->pending_events; seized_events = _Event_sets_Get( pending_events, event_in ); @@ -56,18 +57,20 @@ void _Event_Seize( (seized_events == event_in || _Options_Is_any( option_set )) ) { event->pending_events = _Event_sets_Clear( pending_events, seized_events ); - _ISR_Enable( level ); + _Objects_Release_and_ISR_enable( &executing->Object, lock_context ); *event_out = seized_events; return; } if ( _Options_Is_no_wait( option_set ) ) { - _ISR_Enable( level ); + _Objects_Release_and_ISR_enable( &executing->Object, lock_context ); executing->Wait.return_code = RTEMS_UNSATISFIED; *event_out = seized_events; return; } + intend_to_block = wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK; + /* * Note what we are waiting for BEFORE we enter the critical section. * The interrupt critical section management code needs this to be @@ -76,41 +79,39 @@ void _Event_Seize( * NOTE: Since interrupts are disabled, this isn't that much of an * issue but better safe than sorry. */ - executing->Wait.option = option_set; - executing->Wait.count = event_in; - executing->Wait.return_argument = event_out; - - *sync_state = THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED; + executing->Wait.option = option_set; + executing->Wait.count = event_in; + executing->Wait.return_argument = event_out; + _Thread_Wait_flags_set( executing, intend_to_block ); - _ISR_Enable( level ); + cpu_self = _Objects_Release_and_thread_dispatch_disable( + &executing->Object, + lock_context + ); + _Giant_Acquire( cpu_self ); if ( ticks ) { _Watchdog_Initialize( &executing->Timer, _Event_Timeout, executing->Object.id, - sync_state + NULL ); _Watchdog_Insert_ticks( &executing->Timer, ticks ); } - _Thread_Set_state( executing, wait_state ); + _Thread_Set_state( executing, block_state ); - _ISR_Disable( level ); - - current_sync_state = *sync_state; - *sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED; - if ( current_sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) { - _ISR_Enable( level ); - return; + success = _Thread_Wait_flags_try_change( + executing, + intend_to_block, + wait_class | THREAD_WAIT_STATE_BLOCKED + ); + if ( !success ) { + _Watchdog_Remove( &executing->Timer ); + _Thread_Unblock( executing ); } - /* - * An interrupt completed the thread's blocking request. - * The blocking thread was satisfied by an ISR or timed out. - * - * WARNING! Entering with interrupts disabled and returning with interrupts - * enabled! - */ - _Thread_blocking_operation_Cancel( current_sync_state, executing, level ); + _Giant_Release( cpu_self ); + _Thread_Dispatch_enable( cpu_self ); } |