[rtems commit] score: Fix resource count for self-contained mutex

Sebastian Huber sebh at rtems.org
Mon Sep 14 10:58:33 UTC 2015


Module:    rtems
Branch:    master
Commit:    314ff3c43ff1c00232e201df68e39cc0e5600d95
Changeset: http://git.rtems.org/rtems/commit/?id=314ff3c43ff1c00232e201df68e39cc0e5600d95

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Sep 14 07:10:24 2015 +0200

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 f03bab7..b4b6d44 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 8e4e3b8..438dd97 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);



More information about the vc mailing list