[rtems commit] sptests/spmutex01: add tests for lock nesting

Gedare Bloom gedare at rtems.org
Mon Apr 2 03:16:03 UTC 2018


Module:    rtems
Branch:    4.10
Commit:    f9126f6629c2570672a9fe0af0b605a0cb21496f
Changeset: http://git.rtems.org/rtems/commit/?id=f9126f6629c2570672a9fe0af0b605a0cb21496f

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Wed Jun 22 17:09:23 2016 +0200

sptests/spmutex01: add tests for lock nesting

---

 testsuites/sptests/spmutex01/init.c | 141 ++++++++++++++++++++++++++++++++++--
 1 file changed, 134 insertions(+), 7 deletions(-)

diff --git a/testsuites/sptests/spmutex01/init.c b/testsuites/sptests/spmutex01/init.c
index c363370..72e458f 100644
--- a/testsuites/sptests/spmutex01/init.c
+++ b/testsuites/sptests/spmutex01/init.c
@@ -41,13 +41,14 @@ typedef enum {
   REQ_MTX_0_OBTAIN = RTEMS_EVENT_2,
   REQ_MTX_0_RELEASE = RTEMS_EVENT_3,
   REQ_MTX_1_OBTAIN = RTEMS_EVENT_4,
-  REQ_MTX_1_RELEASE = RTEMS_EVENT_5,
-  REQ_MTX_2_OBTAIN = RTEMS_EVENT_6,
-  REQ_MTX_2_RELEASE = RTEMS_EVENT_7,
-  REQ_MTX_C11_OBTAIN = RTEMS_EVENT_8,
-  REQ_MTX_C11_RELEASE = RTEMS_EVENT_9,
-  REQ_MTX_POSIX_OBTAIN = RTEMS_EVENT_10,
-  REQ_MTX_POSIX_RELEASE = RTEMS_EVENT_11
+  REQ_MTX_1_OBTAIN_TIMEOUT = RTEMS_EVENT_5,
+  REQ_MTX_1_RELEASE = RTEMS_EVENT_6,
+  REQ_MTX_2_OBTAIN = RTEMS_EVENT_7,
+  REQ_MTX_2_RELEASE = RTEMS_EVENT_8,
+  REQ_MTX_C11_OBTAIN = RTEMS_EVENT_9,
+  REQ_MTX_C11_RELEASE = RTEMS_EVENT_10,
+  REQ_MTX_POSIX_OBTAIN = RTEMS_EVENT_11,
+  REQ_MTX_POSIX_RELEASE = RTEMS_EVENT_12
 } request_id;
 
 typedef enum {
@@ -110,6 +111,14 @@ static void send_event(test_context *ctx, task_id id, rtems_event_set events)
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 }
 
+static void wait(void)
+{
+  rtems_status_code sc;
+
+  sc = rtems_task_wake_after(4);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
 static rtems_event_set wait_for_events(void)
 {
   rtems_event_set events;
@@ -141,6 +150,14 @@ static void request(test_context *ctx, task_id id, request_id req)
   sync_with_helper(ctx);
 }
 
+static void obtain_timeout(test_context *ctx, mutex_id id)
+{
+  rtems_status_code sc;
+
+  sc = rtems_semaphore_obtain(ctx->mtx[id], RTEMS_WAIT, 2);
+  rtems_test_assert(sc == RTEMS_TIMEOUT);
+}
+
 static void obtain(test_context *ctx, mutex_id id)
 {
   rtems_status_code sc;
@@ -249,6 +266,22 @@ static void assert_prio(
   rtems_test_assert(expected == actual);
 }
 
+static void change_prio(
+  test_context *ctx,
+  task_id id,
+  rtems_task_priority prio
+)
+{
+  rtems_status_code sc;
+
+  sc = rtems_task_set_priority(
+    ctx->tasks[id],
+    prio,
+    &prio
+  );
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
 static void helper(rtems_task_argument arg)
 {
   test_context *ctx = &test_instance;
@@ -283,6 +316,11 @@ static void worker(rtems_task_argument arg)
       ++ctx->generation[id];
     }
 
+    if ((events & REQ_MTX_1_OBTAIN_TIMEOUT) != 0) {
+      obtain_timeout(ctx, MTX_1);
+      ++ctx->generation[id];
+    }
+
     if ((events & REQ_MTX_1_RELEASE) != 0) {
       release(ctx, MTX_1);
       ++ctx->generation[id];
@@ -370,10 +408,19 @@ static void set_up(test_context *ctx)
 
 static void test_inherit(test_context *ctx)
 {
+  assert_prio(ctx, M, 3);
   obtain(ctx, MTX_0);
   request(ctx, A_1, REQ_MTX_0_OBTAIN);
   check_generations(ctx, NONE, NONE);
   assert_prio(ctx, M, 1);
+  change_prio(ctx, A_1, 2);
+  assert_prio(ctx, M, 2);
+  change_prio(ctx, A_1, 3);
+  assert_prio(ctx, M, 3);
+  change_prio(ctx, A_1, 4);
+  assert_prio(ctx, M, 3);
+  change_prio(ctx, A_1, 1);
+  assert_prio(ctx, M, 1);
   release(ctx, MTX_0);
   check_generations(ctx, A_1, NONE);
   assert_prio(ctx, M, 3);
@@ -383,6 +430,7 @@ static void test_inherit(test_context *ctx)
 
 static void test_inherit_fifo_for_equal_priority(test_context *ctx)
 {
+  assert_prio(ctx, M, 3);
   obtain(ctx, MTX_0);
   request(ctx, A_2_0, REQ_MTX_0_OBTAIN);
   request(ctx, A_1, REQ_MTX_0_OBTAIN);
@@ -401,6 +449,82 @@ static void test_inherit_fifo_for_equal_priority(test_context *ctx)
   check_generations(ctx, A_2_1, NONE);
 }
 
+static void test_inherit_nested_vertical(test_context *ctx)
+{
+  assert_prio(ctx, M, 3);
+  obtain(ctx, MTX_0);
+  obtain(ctx, MTX_1);
+  request(ctx, A_1, REQ_MTX_1_OBTAIN);
+  check_generations(ctx, NONE, NONE);
+  assert_prio(ctx, M, 1);
+  release(ctx, MTX_1);
+  check_generations(ctx, A_1, NONE);
+  assert_prio(ctx, M, 3);
+  request(ctx, A_1, REQ_MTX_1_RELEASE);
+  check_generations(ctx, A_1, NONE);
+  release(ctx, MTX_0);
+}
+
+static void test_inherit_nested_vertical_timeout(test_context *ctx)
+{
+  assert_prio(ctx, M, 3);
+  obtain(ctx, MTX_0);
+  obtain(ctx, MTX_1);
+  request(ctx, A_1, REQ_MTX_1_OBTAIN_TIMEOUT);
+  check_generations(ctx, NONE, NONE);
+  assert_prio(ctx, M, 1);
+  wait();
+  check_generations(ctx, A_1, NONE);
+  assert_prio(ctx, M, 3);
+  release(ctx, MTX_1);
+  release(ctx, MTX_0);
+}
+
+static void test_inherit_nested_horizontal(test_context *ctx)
+{
+  assert_prio(ctx, M, 3);
+  obtain(ctx, MTX_0);
+  request(ctx, A_2_0, REQ_MTX_1_OBTAIN);
+  check_generations(ctx, A_2_0, NONE);
+  request(ctx, A_2_0, REQ_MTX_0_OBTAIN);
+  check_generations(ctx, NONE, NONE);
+  assert_prio(ctx, M, 2);
+  request(ctx, A_1, REQ_MTX_1_OBTAIN_TIMEOUT);
+  check_generations(ctx, NONE, NONE);
+  assert_prio(ctx, A_2_0, 1);
+  assert_prio(ctx, M, 1);
+  wait();
+  check_generations(ctx, A_1, NONE);
+  assert_prio(ctx, A_2_0, 2);
+  assert_prio(ctx, M, 2);
+  request(ctx, A_1, REQ_MTX_1_OBTAIN);
+  check_generations(ctx, NONE, NONE);
+  assert_prio(ctx, A_2_0, 1);
+  assert_prio(ctx, M, 1);
+  change_prio(ctx, A_1, 2);
+  assert_prio(ctx, M, 2);
+  change_prio(ctx, A_1, 3);
+  assert_prio(ctx, M, 2);
+  change_prio(ctx, A_2_0, 3);
+  assert_prio(ctx, M, 3);
+  change_prio(ctx, A_2_0, 2);
+  assert_prio(ctx, M, 2);
+  change_prio(ctx, A_1, 1);
+  assert_prio(ctx, M, 1);
+  release(ctx, MTX_0);
+  check_generations(ctx, A_2_0, NONE);
+  assert_prio(ctx, A_2_0, 1);
+  assert_prio(ctx, M, 3);
+  request(ctx, A_2_0, REQ_MTX_0_RELEASE);
+  check_generations(ctx, A_2_0, NONE);
+  assert_prio(ctx, A_2_0, 1);
+  request(ctx, A_2_0, REQ_MTX_1_RELEASE);
+  check_generations(ctx, A_1, A_2_0);
+  assert_prio(ctx, A_2_0, 2);
+  request(ctx, A_1, REQ_MTX_1_RELEASE);
+  check_generations(ctx, A_1, NONE);
+}
+
 static void test_deadlock_two_classic(test_context *ctx)
 {
   obtain(ctx, MTX_0);
@@ -547,6 +671,9 @@ static void Init(rtems_task_argument arg)
   set_up(ctx);
   test_inherit(ctx);
   test_inherit_fifo_for_equal_priority(ctx);
+  test_inherit_nested_vertical(ctx);
+  test_inherit_nested_vertical_timeout(ctx);
+  test_inherit_nested_horizontal(ctx);
   test_deadlock_two_classic(ctx);
   test_deadlock_three_classic(ctx);
   test_deadlock_c11_and_classic(ctx);




More information about the vc mailing list