From 93306058c0417b1c6e950b44ef279e096062dfba Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 27 May 2016 14:43:19 +0200 Subject: 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(). --- cpukit/score/src/futex.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'cpukit/score/src/futex.c') diff --git a/cpukit/score/src/futex.c b/cpukit/score/src/futex.c index 980c7fbccc..a192509f5c 100644 --- a/cpukit/score/src/futex.c +++ b/cpukit/score/src/futex.c @@ -50,52 +50,56 @@ static Futex_Control *_Futex_Get( struct _Futex_Control *_futex ) static Thread_Control *_Futex_Queue_acquire( Futex_Control *futex, - ISR_lock_Context *lock_context + Thread_queue_Context *queue_context ) { Thread_Control *executing; - _ISR_lock_ISR_disable( lock_context ); + _ISR_lock_ISR_disable( &queue_context->Lock_context ); executing = _Thread_Executing; _Thread_queue_Queue_acquire_critical( &futex->Queue.Queue, &executing->Potpourri_stats, - lock_context + &queue_context->Lock_context ); return executing; } static void _Futex_Queue_release( - Futex_Control *futex, - ISR_lock_Context *lock_context + Futex_Control *futex, + Thread_queue_Context *queue_context ) { - _Thread_queue_Queue_release( &futex->Queue.Queue, lock_context ); + _Thread_queue_Queue_release( + &futex->Queue.Queue, + &queue_context->Lock_context + ); } int _Futex_Wait( struct _Futex_Control *_futex, int *uaddr, int val ) { - Futex_Control *futex; - ISR_lock_Context lock_context; - Thread_Control *executing; - int eno; + Futex_Control *futex; + Thread_queue_Context queue_context; + Thread_Control *executing; + int eno; futex = _Futex_Get( _futex ); - executing = _Futex_Queue_acquire( futex, &lock_context ); + executing = _Futex_Queue_acquire( futex, &queue_context ); if ( *uaddr == val ) { + _Thread_queue_Context_set_expected_level( &queue_context, 1 ); _Thread_queue_Enqueue_critical( &futex->Queue.Queue, FUTEX_TQ_OPERATIONS, executing, STATES_WAITING_FOR_SYS_LOCK_FUTEX, WATCHDOG_NO_TIMEOUT, - &lock_context + &queue_context ); eno = 0; } else { - _Futex_Queue_release( futex, &lock_context ); + _Futex_Queue_release( futex, &queue_context ); eno = EWOULDBLOCK; } @@ -128,11 +132,11 @@ static Thread_Control *_Futex_Flush_filter( int _Futex_Wake( struct _Futex_Control *_futex, int count ) { - Futex_Control *futex; + Futex_Control *futex; Futex_Context context; futex = _Futex_Get( _futex ); - _Futex_Queue_acquire( futex, &context.Base.Lock_context ); + _Futex_Queue_acquire( futex, &context.Base ); /* * For some synchronization objects like barriers the _Futex_Wake() must be @@ -140,7 +144,7 @@ int _Futex_Wake( struct _Futex_Control *_futex, int count ) * check this condition early. */ if ( __predict_true( _Thread_queue_Is_empty( &futex->Queue.Queue ) ) ) { - _Futex_Queue_release( futex, &context.Base.Lock_context ); + _Futex_Queue_release( futex, &context.Base ); return 0; } -- cgit v1.2.3