[rtems commit] smptests/smpthreadlife01: Add test cases

Sebastian Huber sebh at rtems.org
Mon Mar 31 13:39:27 UTC 2014


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

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Mar 31 15:45:01 2014 +0200

smptests/smpthreadlife01: Add test cases

---

 testsuites/smptests/smpthreadlife01/init.c         |  165 ++++++++++++++++++--
 .../smptests/smpthreadlife01/smpthreadlife01.doc   |    5 +
 2 files changed, 159 insertions(+), 11 deletions(-)

diff --git a/testsuites/smptests/smpthreadlife01/init.c b/testsuites/smptests/smpthreadlife01/init.c
index 83e742e..67cd53f 100644
--- a/testsuites/smptests/smpthreadlife01/init.c
+++ b/testsuites/smptests/smpthreadlife01/init.c
@@ -19,8 +19,10 @@
 #include "tmacros.h"
 
 #include <rtems.h>
+#include <rtems/counter.h>
 #include <rtems/libcsupport.h>
 #include <rtems/score/smpbarrier.h>
+#include <rtems/score/threadimpl.h>
 
 const char rtems_test_name[] = "SMPTHREADLIFE 1";
 
@@ -31,11 +33,14 @@ typedef struct {
   volatile rtems_task_argument worker_arg;
   volatile bool terminated;
   SMP_barrier_Control barrier;
+  SMP_barrier_State main_barrier_state;
   SMP_barrier_State worker_barrier_state;
+  Thread_Control *delay_switch_for_executing;
 } test_context;
 
 static test_context test_instance = {
   .barrier = SMP_BARRIER_CONTROL_INITIALIZER,
+  .main_barrier_state = SMP_BARRIER_STATE_INITIALIZER,
   .worker_barrier_state = SMP_BARRIER_STATE_INITIALIZER
 };
 
@@ -62,6 +67,22 @@ static void terminate_extension(Thread_Control *executing)
   ctx->terminated = true;
 }
 
+static void switch_extension(Thread_Control *executing, Thread_Control *heir)
+{
+  test_context *ctx = &test_instance;
+
+  if (ctx->delay_switch_for_executing == executing) {
+    ctx->delay_switch_for_executing = NULL;
+    _SMP_barrier_Wait(&ctx->barrier, &ctx->worker_barrier_state, CPU_COUNT);
+    rtems_counter_delay_nanoseconds(100000000);
+  }
+}
+
+typedef void( *User_extensions_thread_switch_extension )(
+  Thread_Control *executing,
+  Thread_Control *heir
+);
+
 static void worker_task(rtems_task_argument arg)
 {
   test_context *ctx = &test_instance;
@@ -77,10 +98,9 @@ static void worker_task(rtems_task_argument arg)
   }
 }
 
-static void test(void)
+static void test_restart(void)
 {
   test_context *ctx = &test_instance;
-  SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER;
   rtems_status_code sc;
   rtems_id id;
   rtems_task_argument arg;
@@ -101,11 +121,7 @@ static void test(void)
   sc = rtems_task_start(id, worker_task, 0);
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
-  _SMP_barrier_Wait(
-    &ctx->barrier,
-    &barrier_state,
-    CPU_COUNT
-  );
+  _SMP_barrier_Wait(&ctx->barrier, &ctx->main_barrier_state, CPU_COUNT);
 
   for (arg = 1; arg < 23; ++arg) {
     ctx->main_arg = arg;
@@ -114,7 +130,7 @@ static void test(void)
     sc = rtems_task_restart(id, arg);
     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
-    _SMP_barrier_Wait(&ctx->barrier, &barrier_state, CPU_COUNT);
+    _SMP_barrier_Wait(&ctx->barrier, &ctx->main_barrier_state, CPU_COUNT);
 
     rtems_test_assert(ctx->worker_arg == arg);
   }
@@ -123,6 +139,17 @@ static void test(void)
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
   rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
+}
+
+static void test_delete(void)
+{
+  test_context *ctx = &test_instance;
+  rtems_status_code sc;
+  rtems_id id;
+  rtems_task_argument arg;
+  rtems_resource_snapshot snapshot;
+
+  rtems_resource_snapshot_take(&snapshot);
 
   for (arg = 31; arg < 57; ++arg) {
     ctx->main_arg = arg;
@@ -142,7 +169,7 @@ static void test(void)
     sc = rtems_task_start(id, worker_task, arg);
     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
-    _SMP_barrier_Wait(&ctx->barrier, &barrier_state, CPU_COUNT);
+    _SMP_barrier_Wait(&ctx->barrier, &ctx->main_barrier_state, CPU_COUNT);
 
     rtems_test_assert(ctx->worker_arg == arg);
     rtems_test_assert(!ctx->terminated);
@@ -156,12 +183,127 @@ static void test(void)
   }
 }
 
+static void delay_ipi_task(rtems_task_argument arg)
+{
+  test_context *ctx = &test_instance;
+  rtems_interrupt_level level;
+
+  rtems_interrupt_disable(level);
+  (void) level;
+
+  _SMP_barrier_Wait(&ctx->barrier, &ctx->worker_barrier_state, CPU_COUNT);
+
+  /*
+   * Interrupts are disabled, so the inter-processor interrupt deleting us will
+   * be delayed a bit.
+   */
+  rtems_counter_delay_nanoseconds(100000000);
+
+  /* We get deleted as a side effect of enabling the thread life protection */
+  _Thread_Set_life_protection(true);
+  rtems_test_assert(0);
+}
+
+static void test_set_life_protection(void)
+{
+  test_context *ctx = &test_instance;
+  rtems_status_code sc;
+  rtems_id id;
+  rtems_resource_snapshot snapshot;
+
+  rtems_resource_snapshot_take(&snapshot);
+
+  sc = rtems_task_create(
+    rtems_build_name('D', 'E', 'L', 'Y'),
+    1,
+    RTEMS_MINIMUM_STACK_SIZE,
+    RTEMS_DEFAULT_MODES,
+    RTEMS_DEFAULT_ATTRIBUTES,
+    &id
+  );
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_start(id, delay_ipi_task, 0);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  _SMP_barrier_Wait(&ctx->barrier, &ctx->main_barrier_state, CPU_COUNT);
+
+  sc = rtems_task_delete(id);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
+}
+
+static void delay_switch_task(rtems_task_argument arg)
+{
+  test_context *ctx = &test_instance;
+  rtems_status_code sc;
+  rtems_interrupt_level level;
+
+  rtems_interrupt_disable(level);
+  (void) level;
+
+  ctx->delay_switch_for_executing = _Thread_Get_executing();
+
+  _SMP_barrier_Wait(&ctx->barrier, &ctx->worker_barrier_state, CPU_COUNT);
+
+  sc = rtems_task_delete(RTEMS_SELF);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void test_wait_for_execution_stop(void)
+{
+  test_context *ctx = &test_instance;
+  rtems_status_code sc;
+  rtems_id id;
+  rtems_resource_snapshot snapshot;
+
+  rtems_resource_snapshot_take(&snapshot);
+
+  sc = rtems_task_create(
+    rtems_build_name('S', 'W', 'I', 'T'),
+    1,
+    RTEMS_MINIMUM_STACK_SIZE,
+    RTEMS_DEFAULT_MODES,
+    RTEMS_DEFAULT_ATTRIBUTES,
+    &id
+  );
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_start(id, delay_switch_task, 0);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  /* Wait for delay switch task */
+  _SMP_barrier_Wait(&ctx->barrier, &ctx->main_barrier_state, CPU_COUNT);
+
+  /* Wait for delay switch extension */
+  _SMP_barrier_Wait(&ctx->barrier, &ctx->main_barrier_state, CPU_COUNT);
+
+  sc = rtems_task_create(
+    rtems_build_name('W', 'A', 'I', 'T'),
+    1,
+    RTEMS_MINIMUM_STACK_SIZE,
+    RTEMS_DEFAULT_MODES,
+    RTEMS_DEFAULT_ATTRIBUTES,
+    &id
+  );
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_delete(id);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
+}
+
 static void Init(rtems_task_argument arg)
 {
   TEST_BEGIN();
 
   if (rtems_smp_get_processor_count() >= CPU_COUNT) {
-    test();
+    test_restart();
+    test_delete();
+    test_set_life_protection();
+    test_wait_for_execution_stop();
   }
 
   TEST_END();
@@ -181,7 +323,8 @@ static void Init(rtems_task_argument arg)
   { \
     .thread_restart = restart_extension, \
     .thread_delete = delete_extension, \
-    .thread_terminate = terminate_extension \
+    .thread_terminate = terminate_extension, \
+    .thread_switch = switch_extension \
   }, \
   RTEMS_TEST_INITIAL_EXTENSION
 
diff --git a/testsuites/smptests/smpthreadlife01/smpthreadlife01.doc b/testsuites/smptests/smpthreadlife01/smpthreadlife01.doc
index f620567..54fb858 100644
--- a/testsuites/smptests/smpthreadlife01/smpthreadlife01.doc
+++ b/testsuites/smptests/smpthreadlife01/smpthreadlife01.doc
@@ -5,7 +5,12 @@ test set name: smprestart01
 directives:
 
   - rtems_task_restart()
+  - _Thread_Set_life_protection()
+  - _Thread_Wait_for_execution_stop()
 
 concepts:
 
   - Ensure that a restart of a task executing on another processor works.
+  - Ensure that a _Thread_Set_life_protection() works on SMP in case interrupt
+    processing is delayed.
+  - Ensure that _Thread_Wait_for_execution_stop() works on SMP.




More information about the vc mailing list