summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2015-09-14 07:10:24 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2015-09-14 08:30:09 +0200
commit314ff3c43ff1c00232e201df68e39cc0e5600d95 (patch)
treef5bffe857022278f8eb57e3a76bb0b670397a7ae
parentrbheap: Fix rtems_rbheap_free() (diff)
downloadrtems-314ff3c43ff1c00232e201df68e39cc0e5600d95.tar.bz2
score: Fix resource count for self-contained mutex
-rw-r--r--cpukit/score/src/mutex.c5
-rw-r--r--testsuites/sptests/spsyslock01/init.c35
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 <sys/lock.h>
#include <errno.h>
#include <limits.h>
+#include <pthread.h>
#include <string.h>
#include <time.h>
@@ -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);