From 314ff3c43ff1c00232e201df68e39cc0e5600d95 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 14 Sep 2015 07:10:24 +0200 Subject: score: Fix resource count for self-contained mutex --- cpukit/score/src/mutex.c | 5 +++-- testsuites/sptests/spsyslock01/init.c | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/cpukit/score/src/mutex.c b/cpukit/score/src/mutex.c index f03bab76ee..b4b6d4471e 100644 --- a/cpukit/score/src/mutex.c +++ b/cpukit/score/src/mutex.c @@ -141,6 +141,7 @@ static void _Mutex_Release_slow( first = ( *operations->first )( heads ); mutex->owner = first; + ++first->resource_count; unblock = _Thread_queue_Extract_locked( &mutex->Queue.Queue, operations, @@ -214,10 +215,10 @@ void _Mutex_Acquire( struct _Mutex_Control *_mutex ) executing = _Mutex_Queue_acquire( mutex, &lock_context ); owner = mutex->owner; - ++executing->resource_count; if ( __predict_true( owner == NULL ) ) { mutex->owner = executing; + ++executing->resource_count; _Mutex_Queue_release( mutex, &lock_context ); } else { _Mutex_Acquire_slow( mutex, owner, executing, 0, &lock_context ); @@ -238,10 +239,10 @@ int _Mutex_Acquire_timed( executing = _Mutex_Queue_acquire( mutex, &lock_context ); owner = mutex->owner; - ++executing->resource_count; if ( __predict_true( owner == NULL ) ) { mutex->owner = executing; + ++executing->resource_count; _Mutex_Queue_release( mutex, &lock_context ); return 0; diff --git a/testsuites/sptests/spsyslock01/init.c b/testsuites/sptests/spsyslock01/init.c index 8e4e3b8b10..438dd97030 100644 --- a/testsuites/sptests/spsyslock01/init.c +++ b/testsuites/sptests/spsyslock01/init.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -55,6 +56,7 @@ typedef struct { rtems_id mid; rtems_id low; struct _Mutex_Control mtx; + struct _Mutex_Control deadlock_mtx; struct _Mutex_recursive_Control rec_mtx; struct _Condition_Control cond; struct _Semaphore_Control sem; @@ -491,6 +493,19 @@ static void mid_task(rtems_task_argument arg) rtems_test_assert(0); } +static void deadlock_cleanup(void *arg) +{ + struct _Mutex_Control *deadlock_mtx = arg; + + /* + * The thread terminate procedure will dequeue us from the wait queue. So, + * one release is sufficient. + */ + + _Mutex_Release(deadlock_mtx); + _Mutex_Destroy(deadlock_mtx); +} + static void high_task(rtems_task_argument idx) { test_context *ctx = &test_instance; @@ -537,10 +552,15 @@ static void high_task(rtems_task_argument idx) } if ((events & EVENT_MTX_DEADLOCK) != 0) { - struct _Mutex_Control dead = _MUTEX_INITIALIZER; + struct _Mutex_Control *deadlock_mtx = &ctx->deadlock_mtx; + + pthread_cleanup_push(deadlock_cleanup, deadlock_mtx); + + _Mutex_Initialize(deadlock_mtx); + _Mutex_Acquire(deadlock_mtx); + _Mutex_Acquire(deadlock_mtx); - _Mutex_Acquire(&dead); - _Mutex_Acquire(&dead); + pthread_cleanup_pop(0); } if ((events & EVENT_REC_MTX_ACQUIRE) != 0) { @@ -653,6 +673,15 @@ static void test(void) send_event(ctx, 0, EVENT_MTX_DEADLOCK); + sc = rtems_task_delete(ctx->mid); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_delete(ctx->high[0]); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_delete(ctx->high[1]); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + _Mutex_Destroy(&ctx->mtx); _Mutex_recursive_Destroy(&ctx->rec_mtx); _Condition_Destroy(&ctx->cond); -- cgit v1.2.3