From 7d6e94b12ab94f13d3e769702d50f91be7d5884b Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 4 Mar 2015 08:02:19 +0100 Subject: 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. --- cpukit/rtems/Makefile.am | 1 - cpukit/rtems/include/rtems/rtems/eventimpl.h | 49 +++------- cpukit/rtems/src/event.c | 3 - cpukit/rtems/src/eventdata.c | 23 ----- cpukit/rtems/src/eventreceive.c | 13 +-- cpukit/rtems/src/eventseize.c | 77 +++++++-------- cpukit/rtems/src/eventsend.c | 8 +- cpukit/rtems/src/eventsurrender.c | 139 ++++++++++++++++----------- cpukit/rtems/src/eventtimeout.c | 90 +++++++++-------- cpukit/rtems/src/systemeventreceive.c | 13 +-- cpukit/rtems/src/systemeventsend.c | 8 +- cpukit/rtems/src/tasks.c | 2 - testsuites/sptests/spintrcritical10/init.c | 64 ++++++------ testsuites/sptests/spintrcritical21/init.c | 14 ++- testsuites/sptests/spsize/size.c | 2 - 15 files changed, 254 insertions(+), 252 deletions(-) delete mode 100644 cpukit/rtems/src/eventdata.c diff --git a/cpukit/rtems/Makefile.am b/cpukit/rtems/Makefile.am index a1fafb1957..5e6f2eafa0 100644 --- a/cpukit/rtems/Makefile.am +++ b/cpukit/rtems/Makefile.am @@ -211,7 +211,6 @@ librtems_a_SOURCES += src/eventseize.c librtems_a_SOURCES += src/eventsend.c librtems_a_SOURCES += src/eventsurrender.c librtems_a_SOURCES += src/eventtimeout.c -librtems_a_SOURCES += src/eventdata.c librtems_a_SOURCES += src/systemeventsend.c librtems_a_SOURCES += src/systemeventreceive.c diff --git a/cpukit/rtems/include/rtems/rtems/eventimpl.h b/cpukit/rtems/include/rtems/rtems/eventimpl.h index 60b6b51c62..460b7ce90d 100644 --- a/cpukit/rtems/include/rtems/rtems/eventimpl.h +++ b/cpukit/rtems/include/rtems/rtems/eventimpl.h @@ -32,16 +32,6 @@ extern "C" { * @{ */ -/** - * This constant is defined to extern most of the time when using - * this header file. However by defining it to nothing, the data - * declared in this header file can be instantiated. This is done - * in a single per manager file. - */ -#ifndef RTEMS_EVENT_EXTERN -#define RTEMS_EVENT_EXTERN extern -#endif - /** * This constant is passed as the event_in to the * rtems_event_receive directive to determine which events are pending. @@ -54,10 +44,6 @@ extern "C" { */ #define EVENT_SETS_NONE_PENDING 0 -RTEMS_EVENT_EXTERN Thread_blocking_operation_States _Event_Sync_state; - -RTEMS_EVENT_EXTERN Thread_blocking_operation_States _System_event_Sync_state; - /** * @brief Event Manager Initialization * @@ -71,30 +57,23 @@ RTEMS_EVENT_EXTERN Thread_blocking_operation_States _System_event_Sync_state; void _Event_Manager_initialization( void ); 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 ); -/** - * @brief Surrender Event - * - * - INTERRUPT LATENCY: - * + before flash - * + after flash - * + check sync - */ void _Event_Surrender( - Thread_Control *the_thread, - rtems_event_set event_in, - Event_Control *event, - Thread_blocking_operation_States *sync_state, - States_Control wait_state + Thread_Control *the_thread, + rtems_event_set event_in, + Event_Control *event, + Thread_Wait_flags wait_class, + ISR_lock_Context *lock_context ); /** diff --git a/cpukit/rtems/src/event.c b/cpukit/rtems/src/event.c index 3a1359e595..7ec44d741d 100644 --- a/cpukit/rtems/src/event.c +++ b/cpukit/rtems/src/event.c @@ -22,9 +22,6 @@ void _Event_Manager_initialization( void ) { - _Event_Sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED; - _System_event_Sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED; - /* * Register the MP Process Packet routine. */ diff --git a/cpukit/rtems/src/eventdata.c b/cpukit/rtems/src/eventdata.c deleted file mode 100644 index 93fa4737ac..0000000000 --- a/cpukit/rtems/src/eventdata.c +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @file - * - * @brief Instantiate RTEMS Event Data - * @ingroup ClassicEvent - */ - -/* - * COPYRIGHT (c) 1989-2007. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#define RTEMS_EVENT_EXTERN - -#include diff --git a/cpukit/rtems/src/eventreceive.c b/cpukit/rtems/src/eventreceive.c index 49fdb2a9c0..07e1c574df 100644 --- a/cpukit/rtems/src/eventreceive.c +++ b/cpukit/rtems/src/eventreceive.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include rtems_status_code rtems_event_receive( rtems_event_set event_in, @@ -33,12 +33,12 @@ rtems_status_code rtems_event_receive( rtems_status_code sc; if ( event_out != NULL ) { - Thread_Control *executing = _Thread_Get_executing(); + ISR_lock_Context lock_context; + Thread_Control *executing = _Thread_Acquire_executing( &lock_context ); RTEMS_API_Control *api = executing->API_Extensions[ THREAD_API_RTEMS ]; Event_Control *event = &api->Event; if ( !_Event_sets_Is_empty( event_in ) ) { - _Thread_Disable_dispatch(); _Event_Seize( event_in, option_set, @@ -46,14 +46,15 @@ rtems_status_code rtems_event_receive( event_out, executing, event, - &_Event_Sync_state, - STATES_WAITING_FOR_EVENT + THREAD_WAIT_CLASS_EVENT, + STATES_WAITING_FOR_EVENT, + &lock_context ); - _Thread_Enable_dispatch(); sc = executing->Wait.return_code; } else { *event_out = event->pending_events; + _Objects_Release_and_ISR_enable( &executing->Object, &lock_context ); sc = RTEMS_SUCCESSFUL; } } else { 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 ); } diff --git a/cpukit/rtems/src/eventsend.c b/cpukit/rtems/src/eventsend.c index 89bc3e111c..bb9ca3344d 100644 --- a/cpukit/rtems/src/eventsend.c +++ b/cpukit/rtems/src/eventsend.c @@ -31,8 +31,9 @@ rtems_status_code rtems_event_send( Thread_Control *thread; Objects_Locations location; RTEMS_API_Control *api; + ISR_lock_Context lock_context; - thread = _Thread_Get( id, &location ); + thread = _Thread_Acquire( id, &location, &lock_context ); switch ( location ) { case OBJECTS_LOCAL: api = thread->API_Extensions[ THREAD_API_RTEMS ]; @@ -40,10 +41,9 @@ rtems_status_code rtems_event_send( thread, event_in, &api->Event, - &_Event_Sync_state, - STATES_WAITING_FOR_EVENT + THREAD_WAIT_CLASS_EVENT, + &lock_context ); - _Objects_Put( &thread->Object ); sc = RTEMS_SUCCESSFUL; break; #ifdef RTEMS_MULTIPROCESSING diff --git a/cpukit/rtems/src/eventsurrender.c b/cpukit/rtems/src/eventsurrender.c index cc3350187e..824912b38d 100644 --- a/cpukit/rtems/src/eventsurrender.c +++ b/cpukit/rtems/src/eventsurrender.c @@ -23,75 +23,100 @@ #include #include -void _Event_Surrender( - Thread_Control *the_thread, - rtems_event_set event_in, - Event_Control *event, - Thread_blocking_operation_States *sync_state, - States_Control wait_state +static void _Event_Satisfy( + Thread_Control *the_thread, + Event_Control *event, + rtems_event_set pending_events, + rtems_event_set seized_events +) +{ + event->pending_events = _Event_sets_Clear( pending_events, seized_events ); + *(rtems_event_set *) the_thread->Wait.return_argument = seized_events; +} + +static bool _Event_Is_satisfied( + const Thread_Control *the_thread, + rtems_event_set pending_events, + rtems_event_set *seized_events ) { - ISR_Level level; - rtems_event_set pending_events; - rtems_event_set event_condition; - rtems_event_set seized_events; rtems_option option_set; + rtems_event_set event_condition; option_set = the_thread->Wait.option; + event_condition = the_thread->Wait.count; + *seized_events = _Event_sets_Get( pending_events, event_condition ); - _ISR_Disable( level ); - _Event_sets_Post( event_in, &event->pending_events ); - pending_events = event->pending_events; + return !_Event_sets_Is_empty( *seized_events ) + && ( *seized_events == event_condition || _Options_Is_any( option_set ) ); +} - /* - * At this point the event condition is a speculative quantity. Later state - * checks will show if the thread actually waits for an event. - */ - event_condition = the_thread->Wait.count; +void _Event_Surrender( + Thread_Control *the_thread, + rtems_event_set event_in, + Event_Control *event, + Thread_Wait_flags wait_class, + ISR_lock_Context *lock_context +) +{ + rtems_event_set pending_events; + rtems_event_set seized_events; + Thread_Wait_flags wait_flags; + bool unblock; + + _Event_sets_Post( event_in, &event->pending_events ); + pending_events = event->pending_events; - seized_events = _Event_sets_Get( pending_events, event_condition ); + wait_flags = _Thread_Wait_flags_get( the_thread ); if ( - !_Event_sets_Is_empty( seized_events ) - && ( seized_events == event_condition || _Options_Is_any( option_set ) ) + ( wait_flags & THREAD_WAIT_CLASS_MASK ) == wait_class + && _Event_Is_satisfied( the_thread, pending_events, &seized_events ) ) { - /* - * 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 - ); - the_thread->Wait.count = 0; - *(rtems_event_set *)the_thread->Wait.return_argument = seized_events; - *sync_state = THREAD_BLOCKING_OPERATION_SATISFIED; - } else if ( _States_Are_set( the_thread->current_state, wait_state ) ) { - event->pending_events = _Event_sets_Clear( - pending_events, - seized_events + Thread_Wait_flags intend_to_block; + Thread_Wait_flags blocked; + bool success; + + intend_to_block = wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK; + blocked = wait_class | THREAD_WAIT_STATE_BLOCKED; + + success = _Thread_Wait_flags_try_change_critical( + the_thread, + intend_to_block, + wait_class | THREAD_WAIT_STATE_INTERRUPT_SATISFIED + ); + if ( success ) { + _Event_Satisfy( the_thread, event, pending_events, seized_events ); + unblock = false; + } else if ( _Thread_Wait_flags_get( the_thread ) == blocked ) { + _Event_Satisfy( the_thread, event, pending_events, seized_events ); + _Thread_Wait_flags_set( + the_thread, + wait_class | THREAD_WAIT_STATE_SATISFIED ); - the_thread->Wait.count = 0; - *(rtems_event_set *)the_thread->Wait.return_argument = seized_events; - - _ISR_Flash( level ); - - if ( !_Watchdog_Is_active( &the_thread->Timer ) ) { - _ISR_Enable( level ); - _Thread_Unblock( the_thread ); - } else { - _Watchdog_Deactivate( &the_thread->Timer ); - _ISR_Enable( level ); - (void) _Watchdog_Remove( &the_thread->Timer ); - _Thread_Unblock( the_thread ); - } - return; + unblock = true; + } else { + unblock = false; } + } else { + unblock = false; + } + + if ( unblock ) { + Per_CPU_Control *cpu_self; + + cpu_self = _Objects_Release_and_thread_dispatch_disable( + &the_thread->Object, + lock_context + ); + _Giant_Acquire( cpu_self ); + + _Watchdog_Remove( &the_thread->Timer ); + _Thread_Unblock( the_thread ); + + _Giant_Release( cpu_self ); + _Thread_Dispatch_enable( cpu_self ); + } else { + _Objects_Release_and_ISR_enable( &the_thread->Object, lock_context ); } - _ISR_Enable( level ); } diff --git a/cpukit/rtems/src/eventtimeout.c b/cpukit/rtems/src/eventtimeout.c index 11d2f118b3..295f0c5b5f 100644 --- a/cpukit/rtems/src/eventtimeout.c +++ b/cpukit/rtems/src/eventtimeout.c @@ -26,55 +26,61 @@ void _Event_Timeout( void *arg ) { - Thread_Control *the_thread; - Objects_Locations location; - ISR_Level level; - Thread_blocking_operation_States *sync_state; + Thread_Control *the_thread; + Objects_Locations location; + ISR_lock_Context lock_context; + Thread_Wait_flags wait_flags; + Thread_Wait_flags wait_class; + Thread_Wait_flags intend_to_block; + Thread_Wait_flags blocked; + bool success; + bool unblock; - sync_state = arg; - - the_thread = _Thread_Get( id, &location ); + the_thread = _Thread_Acquire( id, &location, &lock_context ); switch ( location ) { - case OBJECTS_LOCAL: + wait_flags = _Thread_Wait_flags_get( the_thread ); + wait_class = wait_flags & THREAD_WAIT_CLASS_MASK; + intend_to_block = wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK; + blocked = wait_class | THREAD_WAIT_STATE_BLOCKED; + success = _Thread_Wait_flags_try_change_critical( + the_thread, + intend_to_block, + wait_class | THREAD_WAIT_STATE_INTERRUPT_TIMEOUT + ); - /* - * If the event manager is not synchronized, then it is either - * "nothing happened", "timeout", or "satisfied". If the_thread - * is the executing thread, then it is in the process of blocking - * and it is the thread which is responsible for the synchronization - * process. - * - * If it is not satisfied, then it is "nothing happened" and - * this is the "timeout" transition. After a request is satisfied, - * a timeout is not allowed to occur. - */ - _ISR_Disable( level ); - /* - * Verify that the thread is still waiting for the event condition. - * This test is necessary to avoid state corruption if the timeout - * happens after the event condition is satisfied in - * _Event_Surrender(). A satisfied event condition is indicated with - * count set to zero. - */ - if ( !the_thread->Wait.count ) { - _ISR_Enable( level ); - _Objects_Put_without_thread_dispatch( &the_thread->Object ); - return; - } + if ( success ) { + the_thread->Wait.return_code = RTEMS_TIMEOUT; + unblock = false; + } else if ( _Thread_Wait_flags_get( the_thread ) == blocked ) { + the_thread->Wait.return_code = RTEMS_TIMEOUT; + _Thread_Wait_flags_set( + the_thread, + wait_class | THREAD_WAIT_STATE_TIMEOUT + ); + unblock = true; + } else { + unblock = false; + } - the_thread->Wait.count = 0; - if ( _Thread_Is_executing( the_thread ) ) { - if ( *sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) - *sync_state = THREAD_BLOCKING_OPERATION_TIMEOUT; - } + if ( unblock ) { + Per_CPU_Control *cpu_self; - the_thread->Wait.return_code = RTEMS_TIMEOUT; - _ISR_Enable( level ); - _Thread_Unblock( the_thread ); - _Objects_Put_without_thread_dispatch( &the_thread->Object ); - break; + cpu_self = _Objects_Release_and_thread_dispatch_disable( + &the_thread->Object, + &lock_context + ); + _Giant_Acquire( cpu_self ); + + _Thread_Unblock( the_thread ); + _Giant_Release( cpu_self ); + _Thread_Dispatch_enable( cpu_self ); + } else { + _Objects_Release_and_ISR_enable( &the_thread->Object, &lock_context ); + } + + break; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* impossible */ #endif diff --git a/cpukit/rtems/src/systemeventreceive.c b/cpukit/rtems/src/systemeventreceive.c index c24e19a8ef..394b26e0a8 100644 --- a/cpukit/rtems/src/systemeventreceive.c +++ b/cpukit/rtems/src/systemeventreceive.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include rtems_status_code rtems_event_system_receive( rtems_event_set event_in, @@ -39,12 +39,12 @@ rtems_status_code rtems_event_system_receive( rtems_status_code sc; if ( event_out != NULL ) { - Thread_Control *executing = _Thread_Get_executing(); + ISR_lock_Context lock_context; + Thread_Control *executing = _Thread_Acquire_executing( &lock_context ); RTEMS_API_Control *api = executing->API_Extensions[ THREAD_API_RTEMS ]; Event_Control *event = &api->System_event; if ( !_Event_sets_Is_empty( event_in ) ) { - _Thread_Disable_dispatch(); _Event_Seize( event_in, option_set, @@ -52,14 +52,15 @@ rtems_status_code rtems_event_system_receive( event_out, executing, event, - &_System_event_Sync_state, - STATES_WAITING_FOR_SYSTEM_EVENT + THREAD_WAIT_CLASS_SYSTEM_EVENT, + STATES_WAITING_FOR_SYSTEM_EVENT, + &lock_context ); - _Thread_Enable_dispatch(); sc = executing->Wait.return_code; } else { *event_out = event->pending_events; + _Objects_Release_and_ISR_enable( &executing->Object, &lock_context ); sc = RTEMS_SUCCESSFUL; } } else { diff --git a/cpukit/rtems/src/systemeventsend.c b/cpukit/rtems/src/systemeventsend.c index b2d55524e7..d35127d4bf 100644 --- a/cpukit/rtems/src/systemeventsend.c +++ b/cpukit/rtems/src/systemeventsend.c @@ -37,8 +37,9 @@ rtems_status_code rtems_event_system_send( Thread_Control *thread; Objects_Locations location; RTEMS_API_Control *api; + ISR_lock_Context lock_context; - thread = _Thread_Get( id, &location ); + thread = _Thread_Acquire( id, &location, &lock_context ); switch ( location ) { case OBJECTS_LOCAL: api = thread->API_Extensions[ THREAD_API_RTEMS ]; @@ -46,10 +47,9 @@ rtems_status_code rtems_event_system_send( thread, event_in, &api->System_event, - &_System_event_Sync_state, - STATES_WAITING_FOR_SYSTEM_EVENT + THREAD_WAIT_CLASS_SYSTEM_EVENT, + &lock_context ); - _Objects_Put( &thread->Object ); sc = RTEMS_SUCCESSFUL; break; #ifdef RTEMS_MULTIPROCESSING diff --git a/cpukit/rtems/src/tasks.c b/cpukit/rtems/src/tasks.c index c8c0accab0..237a313421 100644 --- a/cpukit/rtems/src/tasks.c +++ b/cpukit/rtems/src/tasks.c @@ -54,8 +54,6 @@ static bool _RTEMS_tasks_Create_extension( api = created->API_Extensions[ THREAD_API_RTEMS ]; - _Event_Initialize( &api->Event ); - _Event_Initialize( &api->System_event ); _ASR_Create( &api->Signal ); _Thread_Action_initialize( &api->Signal_action, _Signal_Action_handler ); #if !defined(RTEMS_SMP) diff --git a/testsuites/sptests/spintrcritical10/init.c b/testsuites/sptests/spintrcritical10/init.c index 1d6720cd47..4d25ce6b7c 100644 --- a/testsuites/sptests/spintrcritical10/init.c +++ b/testsuites/sptests/spintrcritical10/init.c @@ -16,6 +16,7 @@ #include #include +#include #include const char rtems_test_name[] = "SPINTRCRITICAL 10"; @@ -34,16 +35,28 @@ typedef struct { bool hit; } test_context; +static bool blocks_for_event(Thread_Wait_flags flags) +{ + return flags == (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_INTEND_TO_BLOCK) + || flags == (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_BLOCKED); +} + +static bool interrupts_blocking_op(Thread_Wait_flags flags) +{ + return + flags == (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_INTEND_TO_BLOCK); +} + static void any_satisfy_before_timeout(rtems_id timer, void *arg) { rtems_status_code sc; test_context *ctx = arg; const Thread_Control *thread = ctx->thread; + Thread_Wait_flags flags = _Thread_Wait_flags_get(thread); - if (thread->Wait.count != 0) { - ctx->hit = _Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED; + if (blocks_for_event(flags)) { + ctx->hit = interrupts_blocking_op(flags); - rtems_test_assert(thread->Wait.count == EVENTS); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF ); @@ -52,7 +65,6 @@ static void any_satisfy_before_timeout(rtems_id timer, void *arg) sc = rtems_event_send(thread->Object.id, GREEN); rtems_test_assert(sc == RTEMS_SUCCESSFUL); - rtems_test_assert(thread->Wait.count == 0); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == GREEN ); @@ -61,15 +73,13 @@ static void any_satisfy_before_timeout(rtems_id timer, void *arg) sc = rtems_event_send(thread->Object.id, RED); rtems_test_assert(sc == RTEMS_SUCCESSFUL); - rtems_test_assert(thread->Wait.count == 0); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == GREEN ); rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL); - _Event_Timeout(thread->Object.id, &_Event_Sync_state); + _Event_Timeout(thread->Object.id, NULL); - rtems_test_assert(thread->Wait.count == 0); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == GREEN ); @@ -77,9 +87,12 @@ static void any_satisfy_before_timeout(rtems_id timer, void *arg) if (ctx->hit) { rtems_test_assert( - _Event_Sync_state == THREAD_BLOCKING_OPERATION_SATISFIED + _Thread_Wait_flags_get(thread) + == (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_INTERRUPT_SATISFIED) ); } + + rtems_test_assert(thread->Wait.count == EVENTS); } sc = rtems_timer_reset(timer); @@ -115,7 +128,6 @@ static void test_any_satisfy_before_timeout(test_context *ctx) ); ctx->hit = false; - ctx->thread->Wait.count = 0; sc = rtems_timer_fire_after(ctx->timer, 1, any_satisfy_before_timeout, ctx); rtems_test_assert(sc == RTEMS_SUCCESSFUL); @@ -137,11 +149,11 @@ static void all_satisfy_before_timeout(rtems_id timer, void *arg) rtems_status_code sc; test_context *ctx = arg; const Thread_Control *thread = ctx->thread; + Thread_Wait_flags flags = _Thread_Wait_flags_get(thread); - if (thread->Wait.count != 0) { - ctx->hit = _Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED; + if (blocks_for_event(flags)) { + ctx->hit = interrupts_blocking_op(flags); - rtems_test_assert(thread->Wait.count == EVENTS); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF ); @@ -150,7 +162,6 @@ static void all_satisfy_before_timeout(rtems_id timer, void *arg) sc = rtems_event_send(thread->Object.id, GREEN); rtems_test_assert(sc == RTEMS_SUCCESSFUL); - rtems_test_assert(thread->Wait.count == EVENTS); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF ); @@ -159,15 +170,13 @@ static void all_satisfy_before_timeout(rtems_id timer, void *arg) sc = rtems_event_send(thread->Object.id, RED); rtems_test_assert(sc == RTEMS_SUCCESSFUL); - rtems_test_assert(thread->Wait.count == 0); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == EVENTS ); rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL); - _Event_Timeout(thread->Object.id, &_Event_Sync_state); + _Event_Timeout(thread->Object.id, NULL); - rtems_test_assert(thread->Wait.count == 0); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == EVENTS ); @@ -175,9 +184,12 @@ static void all_satisfy_before_timeout(rtems_id timer, void *arg) if (ctx->hit) { rtems_test_assert( - _Event_Sync_state == THREAD_BLOCKING_OPERATION_SATISFIED + _Thread_Wait_flags_get(thread) + == (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_INTERRUPT_SATISFIED) ); } + + rtems_test_assert(thread->Wait.count == EVENTS); } sc = rtems_timer_reset(timer); @@ -208,7 +220,6 @@ static void test_all_satisfy_before_timeout(test_context *ctx) ); ctx->hit = false; - ctx->thread->Wait.count = 0; sc = rtems_timer_fire_after(ctx->timer, 1, all_satisfy_before_timeout, ctx); rtems_test_assert(sc == RTEMS_SUCCESSFUL); @@ -230,20 +241,18 @@ static void timeout_before_satisfied(rtems_id timer, void *arg) rtems_status_code sc; test_context *ctx = arg; const Thread_Control *thread = ctx->thread; + Thread_Wait_flags flags = _Thread_Wait_flags_get(thread); - if (thread->Wait.count != 0) { - ctx->hit = - _Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED; + if (blocks_for_event(flags)) { + ctx->hit = interrupts_blocking_op(flags); - rtems_test_assert(thread->Wait.count == EVENTS); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF ); rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL); - _Event_Timeout(thread->Object.id, &_Event_Sync_state); + _Event_Timeout(thread->Object.id, NULL); - rtems_test_assert(thread->Wait.count == 0); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF ); @@ -252,7 +261,6 @@ static void timeout_before_satisfied(rtems_id timer, void *arg) sc = rtems_event_send(thread->Object.id, EVENTS); rtems_test_assert(sc == RTEMS_SUCCESSFUL); - rtems_test_assert(thread->Wait.count == 0); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF ); @@ -260,9 +268,12 @@ static void timeout_before_satisfied(rtems_id timer, void *arg) if (ctx->hit) { rtems_test_assert( - _Event_Sync_state == THREAD_BLOCKING_OPERATION_TIMEOUT + _Thread_Wait_flags_get(thread) + == (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_INTERRUPT_TIMEOUT) ); } + + rtems_test_assert(thread->Wait.count == EVENTS); } sc = rtems_timer_reset(timer); @@ -298,7 +309,6 @@ static void test_timeout_before_all_satisfy(test_context *ctx) ); ctx->hit = false; - ctx->thread->Wait.count = 0; sc = rtems_timer_fire_after(ctx->timer, 1, timeout_before_satisfied, ctx); rtems_test_assert(sc == RTEMS_SUCCESSFUL); diff --git a/testsuites/sptests/spintrcritical21/init.c b/testsuites/sptests/spintrcritical21/init.c index 8b1ddcfc37..faa48f717c 100644 --- a/testsuites/sptests/spintrcritical21/init.c +++ b/testsuites/sptests/spintrcritical21/init.c @@ -18,6 +18,7 @@ #include +#include #include const char rtems_test_name[] = "SPINTRCRITICAL 21"; @@ -34,8 +35,16 @@ static volatile bool case_hit; static rtems_id main_task; +static Thread_Control *main_thread; + static rtems_id other_task; +static bool is_case_hit( void ) +{ + return _Thread_Wait_flags_get( main_thread) + == ( THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_INTEND_TO_BLOCK ); +} + static rtems_timer_service_routine test_event_from_isr( rtems_id timer, void *arg @@ -43,7 +52,7 @@ static rtems_timer_service_routine test_event_from_isr( { rtems_status_code status; - if ( _Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) { + if ( is_case_hit() ) { /* * This event send hits the critical section but sends to * another task so doesn't impact this critical section. @@ -84,7 +93,7 @@ static rtems_timer_service_routine test_event_with_timeout_from_isr( { rtems_status_code status; - if ( _Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) { + if ( is_case_hit() ) { /* * We want to catch the task while it is blocking. Otherwise * just send and make it happy. @@ -117,6 +126,7 @@ rtems_task Init( TEST_BEGIN(); main_task = rtems_task_self(); + main_thread = _Thread_Get_executing(); status = rtems_task_create( 0xa5a5a5a5, diff --git a/testsuites/sptests/spsize/size.c b/testsuites/sptests/spsize/size.c index c68199d81d..f427bd25ac 100644 --- a/testsuites/sptests/spsize/size.c +++ b/testsuites/sptests/spsize/size.c @@ -268,8 +268,6 @@ uninitialized = /*dpmemimpl.h*/ (sizeof _Dual_ported_memory_Information) + -/*eventimpl.h*/ (sizeof _Event_Sync_state) + - #if defined(RTEMS_MULTIPROCESSING) /*eventmp.h*/ 0 + #endif -- cgit v1.2.3