summaryrefslogtreecommitdiffstats
path: root/cpukit/posix/src
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-05-27 14:43:19 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-05-30 16:16:21 +0200
commit93306058c0417b1c6e950b44ef279e096062dfba (patch)
tree1a3326d052169d2aec4c4acdd894589d5d84614c /cpukit/posix/src
parentscore: Add _Thread_queue_Context_set_MP_callout() (diff)
downloadrtems-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.c3
-rw-r--r--cpukit/posix/src/killinfo.c9
-rw-r--r--cpukit/posix/src/nanosleep.c3
-rw-r--r--cpukit/posix/src/psignalclearsignals.c7
-rw-r--r--cpukit/posix/src/psignalsetprocesssignals.c7
-rw-r--r--cpukit/posix/src/psignalunblockthread.c15
-rw-r--r--cpukit/posix/src/pthreadjoin.c26
-rw-r--r--cpukit/posix/src/sigaction.c7
-rw-r--r--cpukit/posix/src/sigtimedwait.c26
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
);
/*