diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-05-27 14:43:19 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-05-30 16:16:21 +0200 |
commit | 93306058c0417b1c6e950b44ef279e096062dfba (patch) | |
tree | 1a3326d052169d2aec4c4acdd894589d5d84614c /cpukit/posix/src | |
parent | score: Add _Thread_queue_Context_set_MP_callout() (diff) | |
download | rtems-93306058c0417b1c6e950b44ef279e096062dfba.tar.bz2 |
score: _CORE_mutex_Check_dispatch_for_seize()
Move the safety check performed by
_CORE_mutex_Check_dispatch_for_seize() out of the performance critical
path and generalize it. Blocking on a thread queue with an unexpected
thread dispatch disabled level is illegal in all system states.
Add the expected thread dispatch disable level (which may be 1 or 2
depending on the operation) to Thread_queue_Context and use it in
_Thread_queue_Enqueue_critical().
Diffstat (limited to 'cpukit/posix/src')
-rw-r--r-- | cpukit/posix/src/condwaitsupp.c | 3 | ||||
-rw-r--r-- | cpukit/posix/src/killinfo.c | 9 | ||||
-rw-r--r-- | cpukit/posix/src/nanosleep.c | 3 | ||||
-rw-r--r-- | cpukit/posix/src/psignalclearsignals.c | 7 | ||||
-rw-r--r-- | cpukit/posix/src/psignalsetprocesssignals.c | 7 | ||||
-rw-r--r-- | cpukit/posix/src/psignalunblockthread.c | 15 | ||||
-rw-r--r-- | cpukit/posix/src/pthreadjoin.c | 26 | ||||
-rw-r--r-- | cpukit/posix/src/sigaction.c | 7 | ||||
-rw-r--r-- | cpukit/posix/src/sigtimedwait.c | 26 |
9 files changed, 58 insertions, 45 deletions
diff --git a/cpukit/posix/src/condwaitsupp.c b/cpukit/posix/src/condwaitsupp.c index 9270c36393..7dff27f161 100644 --- a/cpukit/posix/src/condwaitsupp.c +++ b/cpukit/posix/src/condwaitsupp.c @@ -86,13 +86,14 @@ int _POSIX_Condition_variables_Wait_support( } if ( !already_timedout ) { + _Thread_queue_Context_set_expected_level( &queue_context, 2 ); _Thread_queue_Enqueue_critical( &the_cond->Wait_queue.Queue, POSIX_CONDITION_VARIABLES_TQ_OPERATIONS, executing, STATES_WAITING_FOR_CONDITION_VARIABLE, timeout, - &queue_context.Lock_context + &queue_context ); } else { _POSIX_Condition_variables_Release( the_cond, &queue_context ); diff --git a/cpukit/posix/src/killinfo.c b/cpukit/posix/src/killinfo.c index b16b408825..33754af682 100644 --- a/cpukit/posix/src/killinfo.c +++ b/cpukit/posix/src/killinfo.c @@ -75,7 +75,7 @@ int _POSIX_signals_Send( siginfo_t *siginfo; POSIX_signals_Siginfo_node *psiginfo; Thread_queue_Heads *heads; - ISR_lock_Context lock_context; + Thread_queue_Context queue_context; Per_CPU_Control *cpu_self; /* @@ -334,14 +334,15 @@ post_process_signal: */ _POSIX_signals_Set_process_signals( mask ); - _POSIX_signals_Acquire( &lock_context ); + _Thread_queue_Context_initialize( &queue_context ); + _POSIX_signals_Acquire( &queue_context ); if ( _POSIX_signals_Vectors[ sig ].sa_flags == SA_SIGINFO ) { psiginfo = (POSIX_signals_Siginfo_node *) _Chain_Get_unprotected( &_POSIX_signals_Inactive_siginfo ); if ( !psiginfo ) { - _POSIX_signals_Release( &lock_context ); + _POSIX_signals_Release( &queue_context ); _Thread_Dispatch_enable( cpu_self ); rtems_set_errno_and_return_minus_one( EAGAIN ); } @@ -354,7 +355,7 @@ post_process_signal: ); } - _POSIX_signals_Release( &lock_context ); + _POSIX_signals_Release( &queue_context ); DEBUG_STEP("\n"); _Thread_Dispatch_enable( cpu_self ); return 0; diff --git a/cpukit/posix/src/nanosleep.c b/cpukit/posix/src/nanosleep.c index 21b0d15a2a..e0e1b2676e 100644 --- a/cpukit/posix/src/nanosleep.c +++ b/cpukit/posix/src/nanosleep.c @@ -92,7 +92,8 @@ int nanosleep( &_Thread_queue_Operations_FIFO, executing, STATES_DELAYING | STATES_INTERRUPTIBLE_BY_SIGNAL, - ticks + ticks, + 1 ); /* diff --git a/cpukit/posix/src/psignalclearsignals.c b/cpukit/posix/src/psignalclearsignals.c index c7852554e5..39ea41c77c 100644 --- a/cpukit/posix/src/psignalclearsignals.c +++ b/cpukit/posix/src/psignalclearsignals.c @@ -47,7 +47,7 @@ bool _POSIX_signals_Clear_signals( { sigset_t mask; sigset_t signals_unblocked; - ISR_lock_Context lock_context; + Thread_queue_Context queue_context; bool do_callout; POSIX_signals_Siginfo_node *psiginfo; @@ -68,7 +68,8 @@ bool _POSIX_signals_Clear_signals( /* XXX are we sure they can be cleared the same way? */ if ( do_signals_acquire_release ) { - _POSIX_signals_Acquire( &lock_context ); + _Thread_queue_Context_initialize( &queue_context ); + _POSIX_signals_Acquire( &queue_context ); } if ( is_global ) { @@ -102,7 +103,7 @@ bool _POSIX_signals_Clear_signals( } if ( do_signals_acquire_release ) { - _POSIX_signals_Release( &lock_context ); + _POSIX_signals_Release( &queue_context ); } return do_callout; diff --git a/cpukit/posix/src/psignalsetprocesssignals.c b/cpukit/posix/src/psignalsetprocesssignals.c index 8a2586435c..b755c2db89 100644 --- a/cpukit/posix/src/psignalsetprocesssignals.c +++ b/cpukit/posix/src/psignalsetprocesssignals.c @@ -36,9 +36,10 @@ void _POSIX_signals_Set_process_signals( sigset_t mask ) { - ISR_lock_Context lock_context; + Thread_queue_Context queue_context; - _POSIX_signals_Acquire( &lock_context ); + _Thread_queue_Context_initialize( &queue_context ); + _POSIX_signals_Acquire( &queue_context ); _POSIX_signals_Pending |= mask; - _POSIX_signals_Release( &lock_context ); + _POSIX_signals_Release( &queue_context ); } diff --git a/cpukit/posix/src/psignalunblockthread.c b/cpukit/posix/src/psignalunblockthread.c index b4475b268d..d75e454655 100644 --- a/cpukit/posix/src/psignalunblockthread.c +++ b/cpukit/posix/src/psignalunblockthread.c @@ -96,9 +96,9 @@ static void _POSIX_signals_Action_handler( ISR_lock_Context *lock_context ) { - POSIX_API_Control *api; - int signo; - uint32_t hold_errno; + POSIX_API_Control *api; + int signo; + uint32_t hold_errno; (void) action; _Thread_State_release( executing, lock_context ); @@ -135,13 +135,16 @@ static void _POSIX_signals_Action_handler( * processed at all. No point in doing this loop otherwise. */ while (1) { - _POSIX_signals_Acquire( lock_context ); + Thread_queue_Context queue_context; + + _Thread_queue_Context_initialize( &queue_context ); + _POSIX_signals_Acquire( &queue_context ); if ( !(api->signals_unblocked & (api->signals_pending | _POSIX_signals_Pending)) ) { - _POSIX_signals_Release( lock_context ); + _POSIX_signals_Release( &queue_context ); break; } - _POSIX_signals_Release( lock_context ); + _POSIX_signals_Release( &queue_context ); for ( signo = SIGRTMIN ; signo <= SIGRTMAX ; signo++ ) { _POSIX_signals_Check_signal( api, signo, false ); diff --git a/cpukit/posix/src/pthreadjoin.c b/cpukit/posix/src/pthreadjoin.c index f4a0676d6b..86b805132a 100644 --- a/cpukit/posix/src/pthreadjoin.c +++ b/cpukit/posix/src/pthreadjoin.c @@ -32,13 +32,15 @@ static int _POSIX_Threads_Join( pthread_t thread, void **value_ptr ) { - Thread_Control *the_thread; - ISR_lock_Context lock_context; - Per_CPU_Control *cpu_self; - Thread_Control *executing; - void *value; + Thread_Control *the_thread; + Thread_queue_Context queue_context; + Per_CPU_Control *cpu_self; + Thread_Control *executing; + void *value; - the_thread = _Thread_Get( thread, &lock_context ); + _Thread_queue_Context_initialize( &queue_context ); + _Thread_queue_Context_set_expected_level( &queue_context, 1 ); + the_thread = _Thread_Get( thread, &queue_context.Lock_context ); if ( the_thread == NULL ) { return ESRCH; @@ -48,29 +50,29 @@ static int _POSIX_Threads_Join( pthread_t thread, void **value_ptr ) executing = _Per_CPU_Get_executing( cpu_self ); if ( executing == the_thread ) { - _ISR_lock_ISR_enable( &lock_context ); + _ISR_lock_ISR_enable( &queue_context.Lock_context ); return EDEADLK; } - _Thread_State_acquire_critical( the_thread, &lock_context ); + _Thread_State_acquire_critical( the_thread, &queue_context.Lock_context ); if ( !_Thread_Is_joinable( the_thread ) ) { - _Thread_State_release( the_thread, &lock_context ); + _Thread_State_release( the_thread, &queue_context.Lock_context ); return EINVAL; } if ( _States_Is_waiting_for_join_at_exit( the_thread->current_state ) ) { value = the_thread->Life.exit_value; _Thread_Clear_state_locked( the_thread, STATES_WAITING_FOR_JOIN_AT_EXIT ); - _Thread_Dispatch_disable_with_CPU( cpu_self, &lock_context ); - _Thread_State_release( the_thread, &lock_context ); + _Thread_Dispatch_disable_with_CPU( cpu_self, &queue_context.Lock_context ); + _Thread_State_release( the_thread, &queue_context.Lock_context ); _Thread_Dispatch_enable( cpu_self ); } else { _Thread_Join( the_thread, STATES_INTERRUPTIBLE_BY_SIGNAL | STATES_WAITING_FOR_JOIN, executing, - &lock_context + &queue_context ); if ( _POSIX_Get_error_after_wait( executing ) != 0 ) { diff --git a/cpukit/posix/src/sigaction.c b/cpukit/posix/src/sigaction.c index 177dcd19ab..26df98d394 100644 --- a/cpukit/posix/src/sigaction.c +++ b/cpukit/posix/src/sigaction.c @@ -33,7 +33,7 @@ int sigaction( struct sigaction *__restrict oact ) { - ISR_lock_Context lock_context; + Thread_queue_Context queue_context; if ( !sig ) rtems_set_errno_and_return_minus_one( EINVAL ); @@ -51,7 +51,8 @@ int sigaction( if ( sig == SIGKILL ) rtems_set_errno_and_return_minus_one( EINVAL ); - _POSIX_signals_Acquire( &lock_context ); + _Thread_queue_Context_initialize( &queue_context ); + _POSIX_signals_Acquire( &queue_context ); if ( oact ) *oact = _POSIX_signals_Vectors[ sig ]; @@ -76,7 +77,7 @@ int sigaction( } } - _POSIX_signals_Release( &lock_context ); + _POSIX_signals_Release( &queue_context ); return 0; } diff --git a/cpukit/posix/src/sigtimedwait.c b/cpukit/posix/src/sigtimedwait.c index ddc2884d68..7855bb0080 100644 --- a/cpukit/posix/src/sigtimedwait.c +++ b/cpukit/posix/src/sigtimedwait.c @@ -69,14 +69,14 @@ int sigtimedwait( const struct timespec *__restrict timeout ) { - Thread_Control *executing; - POSIX_API_Control *api; - Watchdog_Interval interval; - siginfo_t signal_information; - siginfo_t *the_info; - int signo; - ISR_lock_Context lock_context; - int error; + Thread_Control *executing; + POSIX_API_Control *api; + Watchdog_Interval interval; + siginfo_t signal_information; + siginfo_t *the_info; + int signo; + Thread_queue_Context queue_context; + int error; /* * Error check parameters before disabling interrupts. @@ -115,7 +115,8 @@ int sigtimedwait( /* API signals pending? */ - _POSIX_signals_Acquire( &lock_context ); + _Thread_queue_Context_initialize( &queue_context ); + _POSIX_signals_Acquire( &queue_context ); if ( *set & api->signals_pending ) { /* XXX real info later */ the_info->si_signo = _POSIX_signals_Get_lowest( api->signals_pending ); @@ -127,7 +128,7 @@ int sigtimedwait( false, false ); - _POSIX_signals_Release( &lock_context ); + _POSIX_signals_Release( &queue_context ); the_info->si_code = SI_USER; the_info->si_value.sival_int = 0; @@ -139,7 +140,7 @@ int sigtimedwait( if ( *set & _POSIX_signals_Pending ) { signo = _POSIX_signals_Get_lowest( _POSIX_signals_Pending ); _POSIX_signals_Clear_signals( api, signo, the_info, true, false, false ); - _POSIX_signals_Release( &lock_context ); + _POSIX_signals_Release( &queue_context ); the_info->si_signo = signo; the_info->si_code = SI_USER; @@ -151,13 +152,14 @@ int sigtimedwait( executing->Wait.option = *set; executing->Wait.return_argument = the_info; + _Thread_queue_Context_set_expected_level( &queue_context, 1 ); _Thread_queue_Enqueue_critical( &_POSIX_signals_Wait_queue.Queue, POSIX_SIGNALS_TQ_OPERATIONS, executing, STATES_WAITING_FOR_SIGNAL | STATES_INTERRUPTIBLE_BY_SIGNAL, interval, - &lock_context + &queue_context ); /* |