Remove _Thread_Acquire() and _Thread_Acquire_for_executing(). Add utility functions for the default thread lock. Use the default thread lock for the RTEMS events. There is no need to disable thread dispatching and a Giant acquire in _Event_Timeout() since this was already done by the caller.
Update #2273. --- cpukit/rtems/src/eventreceive.c | 12 ++-- cpukit/rtems/src/eventseize.c | 17 ++--- cpukit/rtems/src/eventsend.c | 3 +- cpukit/rtems/src/eventsurrender.c | 10 +-- cpukit/rtems/src/eventtimeout.c | 74 ++++++++-------------- cpukit/rtems/src/systemeventreceive.c | 12 ++-- cpukit/rtems/src/systemeventsend.c | 3 +- cpukit/score/include/rtems/score/threadimpl.h | 89 ++++++++++++++++++++++++--- cpukit/score/src/threadget.c | 22 ++----- testsuites/sptests/spintrcritical10/init.c | 12 ++-- 10 files changed, 146 insertions(+), 108 deletions(-) diff --git a/cpukit/rtems/src/eventreceive.c b/cpukit/rtems/src/eventreceive.c index 07e1c57..14f93db 100644 --- a/cpukit/rtems/src/eventreceive.c +++ b/cpukit/rtems/src/eventreceive.c @@ -34,9 +34,13 @@ rtems_status_code rtems_event_receive( if ( event_out != NULL ) { 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; + Thread_Control *executing; + RTEMS_API_Control *api; + Event_Control *event; + + executing = _Thread_Lock_acquire_default_for_executing( &lock_context ); + api = executing->API_Extensions[ THREAD_API_RTEMS ]; + event = &api->Event; if ( !_Event_sets_Is_empty( event_in ) ) { _Event_Seize( @@ -54,7 +58,7 @@ rtems_status_code rtems_event_receive( sc = executing->Wait.return_code; } else { *event_out = event->pending_events; - _Objects_Release_and_ISR_enable( &executing->Object, &lock_context ); + _Thread_Lock_release_default( executing, &lock_context ); sc = RTEMS_SUCCESSFUL; } } else { diff --git a/cpukit/rtems/src/eventseize.c b/cpukit/rtems/src/eventseize.c index 59a2b62..9296656 100644 --- a/cpukit/rtems/src/eventseize.c +++ b/cpukit/rtems/src/eventseize.c @@ -57,13 +57,13 @@ void _Event_Seize( (seized_events == event_in || _Options_Is_any( option_set )) ) { event->pending_events = _Event_sets_Clear( pending_events, seized_events ); - _Objects_Release_and_ISR_enable( &executing->Object, lock_context ); + _Thread_Lock_release_default( executing, lock_context ); *event_out = seized_events; return; } if ( _Options_Is_no_wait( option_set ) ) { - _Objects_Release_and_ISR_enable( &executing->Object, lock_context ); + _Thread_Lock_release_default( executing, lock_context ); executing->Wait.return_code = RTEMS_UNSATISFIED; *event_out = seized_events; return; @@ -84,19 +84,12 @@ void _Event_Seize( executing->Wait.return_argument = event_out; _Thread_Wait_flags_set( executing, intend_to_block ); - cpu_self = _Objects_Release_and_thread_dispatch_disable( - &executing->Object, - lock_context - ); + cpu_self = _Thread_Dispatch_disable_critical(); + _Thread_Lock_release_default( executing, lock_context ); _Giant_Acquire( cpu_self ); if ( ticks ) { - _Watchdog_Initialize( - &executing->Timer, - _Event_Timeout, - executing->Object.id, - NULL - ); + _Watchdog_Initialize( &executing->Timer, _Event_Timeout, 0, executing ); _Watchdog_Insert_ticks( &executing->Timer, ticks ); } diff --git a/cpukit/rtems/src/eventsend.c b/cpukit/rtems/src/eventsend.c index bb9ca33..c9e81fb 100644 --- a/cpukit/rtems/src/eventsend.c +++ b/cpukit/rtems/src/eventsend.c @@ -33,7 +33,7 @@ rtems_status_code rtems_event_send( RTEMS_API_Control *api; ISR_lock_Context lock_context; - thread = _Thread_Acquire( id, &location, &lock_context ); + thread = _Thread_Get_interrupt_disable( id, &location, &lock_context ); switch ( location ) { case OBJECTS_LOCAL: api = thread->API_Extensions[ THREAD_API_RTEMS ]; @@ -44,6 +44,7 @@ rtems_status_code rtems_event_send( THREAD_WAIT_CLASS_EVENT, &lock_context ); + _Objects_Put_for_get_isr_disable( &thread->Object ); sc = RTEMS_SUCCESSFUL; break; #ifdef RTEMS_MULTIPROCESSING diff --git a/cpukit/rtems/src/eventsurrender.c b/cpukit/rtems/src/eventsurrender.c index 824912b..ba4e429 100644 --- a/cpukit/rtems/src/eventsurrender.c +++ b/cpukit/rtems/src/eventsurrender.c @@ -64,6 +64,8 @@ void _Event_Surrender( Thread_Wait_flags wait_flags; bool unblock; + _Thread_Lock_acquire_default_critical( the_thread, lock_context ); + _Event_sets_Post( event_in, &event->pending_events ); pending_events = event->pending_events; @@ -105,10 +107,8 @@ void _Event_Surrender( if ( unblock ) { Per_CPU_Control *cpu_self; - cpu_self = _Objects_Release_and_thread_dispatch_disable( - &the_thread->Object, - lock_context - ); + cpu_self = _Thread_Dispatch_disable_critical(); + _Thread_Lock_release_default( the_thread, lock_context ); _Giant_Acquire( cpu_self ); _Watchdog_Remove( &the_thread->Timer ); @@ -117,6 +117,6 @@ void _Event_Surrender( _Giant_Release( cpu_self ); _Thread_Dispatch_enable( cpu_self ); } else { - _Objects_Release_and_ISR_enable( &the_thread->Object, lock_context ); + _Thread_Lock_release_default( the_thread, lock_context ); } } diff --git a/cpukit/rtems/src/eventtimeout.c b/cpukit/rtems/src/eventtimeout.c index 295f0c5..9c09174 100644 --- a/cpukit/rtems/src/eventtimeout.c +++ b/cpukit/rtems/src/eventtimeout.c @@ -27,7 +27,6 @@ void _Event_Timeout( ) { Thread_Control *the_thread; - Objects_Locations location; ISR_lock_Context lock_context; Thread_Wait_flags wait_flags; Thread_Wait_flags wait_class; @@ -36,55 +35,36 @@ void _Event_Timeout( bool success; bool unblock; - 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 - ); + the_thread = arg; + _Thread_Lock_acquire_default( the_thread, &lock_context ); - 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; - } + 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 ( unblock ) { - Per_CPU_Control *cpu_self; - - cpu_self = _Objects_Release_and_thread_dispatch_disable( - &the_thread->Object, - &lock_context - ); - _Giant_Acquire( cpu_self ); - - _Thread_Unblock( the_thread ); + 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; + } - _Giant_Release( cpu_self ); - _Thread_Dispatch_enable( cpu_self ); - } else { - _Objects_Release_and_ISR_enable( &the_thread->Object, &lock_context ); - } + _Thread_Lock_release_default( the_thread, &lock_context ); - break; -#if defined(RTEMS_MULTIPROCESSING) - case OBJECTS_REMOTE: /* impossible */ -#endif - case OBJECTS_ERROR: - break; + if ( unblock ) { + _Thread_Unblock( the_thread ); } } diff --git a/cpukit/rtems/src/systemeventreceive.c b/cpukit/rtems/src/systemeventreceive.c index 394b26e..c33f468 100644 --- a/cpukit/rtems/src/systemeventreceive.c +++ b/cpukit/rtems/src/systemeventreceive.c @@ -40,9 +40,13 @@ rtems_status_code rtems_event_system_receive( if ( event_out != NULL ) { 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; + Thread_Control *executing; + RTEMS_API_Control *api; + Event_Control *event; + + executing = _Thread_Lock_acquire_default_for_executing( &lock_context ); + api = executing->API_Extensions[ THREAD_API_RTEMS ]; + event = &api->System_event; if ( !_Event_sets_Is_empty( event_in ) ) { _Event_Seize( @@ -60,7 +64,7 @@ rtems_status_code rtems_event_system_receive( sc = executing->Wait.return_code; } else { *event_out = event->pending_events; - _Objects_Release_and_ISR_enable( &executing->Object, &lock_context ); + _Thread_Lock_release_default( executing, &lock_context ); sc = RTEMS_SUCCESSFUL; } } else { diff --git a/cpukit/rtems/src/systemeventsend.c b/cpukit/rtems/src/systemeventsend.c index d35127d..1892c13 100644 --- a/cpukit/rtems/src/systemeventsend.c +++ b/cpukit/rtems/src/systemeventsend.c @@ -39,7 +39,7 @@ rtems_status_code rtems_event_system_send( RTEMS_API_Control *api; ISR_lock_Context lock_context; - thread = _Thread_Acquire( id, &location, &lock_context ); + thread = _Thread_Get_interrupt_disable( id, &location, &lock_context ); switch ( location ) { case OBJECTS_LOCAL: api = thread->API_Extensions[ THREAD_API_RTEMS ]; @@ -50,6 +50,7 @@ rtems_status_code rtems_event_system_send( THREAD_WAIT_CLASS_SYSTEM_EVENT, &lock_context ); + _Objects_Put_for_get_isr_disable( &thread->Object ); sc = RTEMS_SUCCESSFUL; break; #ifdef RTEMS_MULTIPROCESSING diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h index 1ccc4d6..9a621a8 100644 --- a/cpukit/score/include/rtems/score/threadimpl.h +++ b/cpukit/score/include/rtems/score/threadimpl.h @@ -22,6 +22,7 @@ #define _RTEMS_SCORE_THREADIMPL_H #include <rtems/score/thread.h> +#include <rtems/score/assert.h> #include <rtems/score/chainimpl.h> #include <rtems/score/interr.h> #include <rtems/score/isr.h> @@ -382,23 +383,16 @@ Thread_Control *_Thread_Get ( ); /** - * @brief Acquires a thread by its identifier. + * @brief Gets a thread by its identifier. * - * @see _Objects_Acquire(). + * @see _Objects_Get_isr_disable(). */ -Thread_Control *_Thread_Acquire( +Thread_Control *_Thread_Get_interrupt_disable( Objects_Id id, Objects_Locations *location, ISR_lock_Context *lock_context ); -/** - * @brief Acquires the executing thread. - * - * @see _Objects_Acquire(). - */ -Thread_Control *_Thread_Acquire_executing( ISR_lock_Context *lock_context ); - RTEMS_INLINE_ROUTINE Per_CPU_Control *_Thread_Get_CPU( const Thread_Control *thread ) @@ -866,6 +860,81 @@ RTEMS_INLINE_ROUTINE bool _Thread_Owns_resources( } /** + * @brief Acquires the default thread lock and returns the executing thread. + * + * @param[in] lock_context The lock context used for the corresponding lock + * release. + * + * @return The executing thread. + * + * @see _Thread_Lock_release_default(). + */ +RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Lock_acquire_default_for_executing( + ISR_lock_Context *lock_context +) +{ + Thread_Control *executing; + + _ISR_lock_ISR_disable( lock_context ); + executing = _Thread_Executing; + _ISR_lock_Acquire( &executing->Lock.Default, lock_context ); + + return executing; +} + +/** + * @brief Acquires the default thread lock inside a critical section + * (interrupts disabled). + * + * @param[in] the_thread The thread. + * @param[in] lock_context The lock context used for the corresponding lock + * release. + * + * @see _Thread_Lock_release_default(). + */ +RTEMS_INLINE_ROUTINE void _Thread_Lock_acquire_default_critical( + Thread_Control *the_thread, + ISR_lock_Context *lock_context +) +{ + _Assert( _ISR_Get_level() != 0 ); + _ISR_lock_Acquire( &the_thread->Lock.Default, lock_context ); +} + +/** + * @brief Acquires the default thread lock. + * + * @param[in] the_thread The thread. + * @param[in] lock_context The lock context used for the corresponding lock + * release. + * + * @see _Thread_Lock_release_default(). + */ +RTEMS_INLINE_ROUTINE void _Thread_Lock_acquire_default( + Thread_Control *the_thread, + ISR_lock_Context *lock_context +) +{ + _Assert( _ISR_Get_level() != 0 ); + _ISR_lock_ISR_disable_and_acquire( &the_thread->Lock.Default, lock_context ); +} + +/** + * @brief Release the default thread lock. + * + * @param[in] the_thread The thread. + * @param[in] lock_context The lock context used for the corresponding lock + * acquire. + */ +RTEMS_INLINE_ROUTINE void _Thread_Lock_release_default( + Thread_Control *the_thread, + ISR_lock_Context *lock_context +) +{ + _ISR_lock_Release_and_ISR_enable( &the_thread->Lock.Default, lock_context ); +} + +/** * @brief Release the thread lock. * * @param[in] lock The lock returned by _Thread_Lock_acquire(). diff --git a/cpukit/score/src/threadget.c b/cpukit/score/src/threadget.c index 1091333..45ea55f 100644 --- a/cpukit/score/src/threadget.c +++ b/cpukit/score/src/threadget.c @@ -75,22 +75,7 @@ Thread_Control *_Thread_Get( return (Thread_Control *) _Objects_Get( information, id, location ); } -Thread_Control *_Thread_Acquire_executing( ISR_lock_Context *lock_context ) -{ - Thread_Control *executing; - -#if defined(RTEMS_SMP) - _ISR_Disable_without_giant( lock_context->Lock_context.isr_level ); -#else - _ISR_Disable( lock_context->isr_level ); -#endif - executing = _Thread_Executing; - _ISR_lock_Acquire( &executing->Object.Lock, lock_context ); - - return executing; -} - -Thread_Control *_Thread_Acquire( +Thread_Control *_Thread_Get_interrupt_disable( Objects_Id id, Objects_Locations *location, ISR_lock_Context *lock_context @@ -100,7 +85,8 @@ Thread_Control *_Thread_Acquire( if ( _Objects_Are_ids_equal( id, OBJECTS_ID_OF_SELF ) ) { *location = OBJECTS_LOCAL; - return _Thread_Acquire_executing( lock_context ); + _ISR_lock_ISR_disable( lock_context ); + return _Thread_Executing; } information = _Thread_Get_objects_information( id ); @@ -110,5 +96,5 @@ Thread_Control *_Thread_Acquire( } return (Thread_Control *) - _Objects_Acquire( information, id, location, lock_context ); + _Objects_Get_isr_disable( information, id, location, lock_context ); } diff --git a/testsuites/sptests/spintrcritical10/init.c b/testsuites/sptests/spintrcritical10/init.c index 4d25ce6..441b161 100644 --- a/testsuites/sptests/spintrcritical10/init.c +++ b/testsuites/sptests/spintrcritical10/init.c @@ -51,7 +51,7 @@ 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_Control *thread = ctx->thread; Thread_Wait_flags flags = _Thread_Wait_flags_get(thread); if (blocks_for_event(flags)) { @@ -78,7 +78,7 @@ static void any_satisfy_before_timeout(rtems_id timer, void *arg) ); rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL); - _Event_Timeout(thread->Object.id, NULL); + _Event_Timeout(0, thread); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == GREEN @@ -148,7 +148,7 @@ 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_Control *thread = ctx->thread; Thread_Wait_flags flags = _Thread_Wait_flags_get(thread); if (blocks_for_event(flags)) { @@ -175,7 +175,7 @@ static void all_satisfy_before_timeout(rtems_id timer, void *arg) ); rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL); - _Event_Timeout(thread->Object.id, NULL); + _Event_Timeout(0, thread); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == EVENTS @@ -240,7 +240,7 @@ 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_Control *thread = ctx->thread; Thread_Wait_flags flags = _Thread_Wait_flags_get(thread); if (blocks_for_event(flags)) { @@ -251,7 +251,7 @@ static void timeout_before_satisfied(rtems_id timer, void *arg) ); rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL); - _Event_Timeout(thread->Object.id, NULL); + _Event_Timeout(0, thread); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF -- 1.8.4.5 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel