[rtems commit] smptests/smpatomic01: New test cases

Sebastian Huber sebh at rtems.org
Wed Jun 1 07:54:19 UTC 2016


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

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Wed Jun  1 09:50:44 2016 +0200

smptests/smpatomic01: New test cases

Demonstrate that a read-modify-write atomic operation may be necessary
on some archtitectures to observe the latest value written.

---

 cpukit/libmisc/testsupport/testparallel.c       |   4 +-
 testsuites/smptests/smpatomic01/init.c          | 175 ++++++++++++++++++++-
 testsuites/smptests/smpatomic01/smpatomic01.scn | 192 ++++++++++++++++++++++--
 3 files changed, 352 insertions(+), 19 deletions(-)

diff --git a/cpukit/libmisc/testsupport/testparallel.c b/cpukit/libmisc/testsupport/testparallel.c
index dabd564..a2f4573 100644
--- a/cpukit/libmisc/testsupport/testparallel.c
+++ b/cpukit/libmisc/testsupport/testparallel.c
@@ -68,7 +68,9 @@ static void run_tests(
       if (rtems_test_parallel_is_master_worker(worker_index)) {
         rtems_interval duration = (*job->init)(ctx, job->arg, active_worker);
 
-        start_worker_stop_timer(ctx, duration);
+        if (duration > 0) {
+          start_worker_stop_timer(ctx, duration);
+        }
       }
 
       _SMP_barrier_Wait(&ctx->barrier, &bs, ctx->worker_count);
diff --git a/testsuites/smptests/smpatomic01/init.c b/testsuites/smptests/smpatomic01/init.c
index 5d0f665..673ff28 100644
--- a/testsuites/smptests/smpatomic01/init.c
+++ b/testsuites/smptests/smpatomic01/init.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2015 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2013, 2016 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
  *  Dornierstr. 4
@@ -19,7 +19,9 @@
 #endif
 
 #include <rtems/score/atomic.h>
+#include <rtems/score/smpbarrier.h>
 #include <rtems.h>
+#include <rtems/bsd.h>
 #include <rtems/test.h>
 #include <limits.h>
 #include <string.h>
@@ -28,6 +30,8 @@
 
 const char rtems_test_name[] = "SMPATOMIC 1";
 
+#define MS_PER_TICK 10
+
 #define MASTER_PRIORITY 1
 
 #define WORKER_PRIORITY 2
@@ -42,6 +46,14 @@ typedef struct {
   char unused_space_for_cache_line_separation[128];
   unsigned long second_value;
   Atomic_Flag global_flag;
+  SMP_barrier_Control barrier;
+  SMP_barrier_State barrier_state[CPU_COUNT];
+  sbintime_t load_trigger_time;
+  sbintime_t load_change_time[CPU_COUNT];
+  int load_count[CPU_COUNT];
+  sbintime_t rmw_trigger_time;
+  sbintime_t rmw_change_time[CPU_COUNT];
+  int rmw_count[CPU_COUNT];
 } smpatomic01_context;
 
 static smpatomic01_context test_instance;
@@ -410,6 +422,159 @@ static void test_atomic_fence_fini(
   );
 }
 
+static rtems_interval test_atomic_store_load_rmw_init(
+  rtems_test_parallel_context *base,
+  void *arg,
+  size_t active_workers
+)
+{
+  smpatomic01_context *ctx = (smpatomic01_context *) base;
+  size_t i;
+
+  _Atomic_Init_ulong(&ctx->atomic_value, 0);
+
+  _SMP_barrier_Control_initialize(&ctx->barrier);
+
+  for (i = 0; i < active_workers; ++i) {
+    _SMP_barrier_State_initialize(&ctx->barrier_state[i]);
+  }
+
+  return 0;
+}
+
+static sbintime_t now(void)
+{
+  struct bintime bt;
+
+  rtems_bsd_binuptime(&bt);
+  return bttosbt(bt);
+}
+
+static void test_atomic_store_load_rmw_body(
+  rtems_test_parallel_context *base,
+  void *arg,
+  size_t active_workers,
+  size_t worker_index
+)
+{
+  smpatomic01_context *ctx = (smpatomic01_context *) base;
+  uint32_t cpu_self_index;
+  sbintime_t t;
+  int counter;
+
+  if (rtems_test_parallel_is_master_worker(worker_index)) {
+    rtems_status_code sc;
+
+    sc = rtems_task_wake_after(1);
+    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+    t = now();
+    t += (MS_PER_TICK / 2) * SBT_1MS;
+    ctx->load_trigger_time = t;
+    t += MS_PER_TICK * SBT_1MS;
+    ctx->rmw_trigger_time = t;
+  }
+
+  _Atomic_Fence(ATOMIC_ORDER_SEQ_CST);
+
+  _SMP_barrier_Wait(
+    &ctx->barrier,
+    &ctx->barrier_state[worker_index],
+    active_workers
+  );
+
+  /*
+   * Use the physical processor index, to observe timing differences introduced
+   * by the system topology.
+   */
+  cpu_self_index = rtems_get_current_processor();
+
+  /* Store release and load acquire test case */
+
+  counter = 0;
+  t = ctx->load_trigger_time;
+
+  while (now() < t) {
+    /* Wait */
+  }
+
+  if (cpu_self_index == 0) {
+    _Atomic_Store_ulong(&ctx->atomic_value, 1, ATOMIC_ORDER_RELEASE);
+  } else {
+    while (_Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_ACQUIRE) == 0) {
+      ++counter;
+    }
+  }
+
+  ctx->load_change_time[cpu_self_index] = now();
+  ctx->load_count[cpu_self_index] = counter;
+
+  /* Read-modify-write test case */
+
+  if (cpu_self_index == 0) {
+    _Atomic_Store_ulong(&ctx->atomic_value, 0, ATOMIC_ORDER_RELAXED);
+  }
+
+  counter = 0;
+  t = ctx->rmw_trigger_time;
+
+  while (now() < t) {
+    /* Wait */
+  }
+
+  if (cpu_self_index == 0) {
+    _Atomic_Store_ulong(&ctx->atomic_value, 1, ATOMIC_ORDER_RELAXED);
+  } else {
+    while (
+      (_Atomic_Fetch_or_ulong(&ctx->atomic_value, 2, ATOMIC_ORDER_RELAXED) & 1)
+        == 0
+    ) {
+      ++counter;
+    }
+  }
+
+  ctx->rmw_change_time[cpu_self_index] = now();
+  ctx->rmw_count[cpu_self_index] = counter;
+}
+
+static void test_atomic_store_load_rmw_fini(
+  rtems_test_parallel_context *base,
+  void *arg,
+  size_t active_workers
+)
+{
+  smpatomic01_context *ctx = (smpatomic01_context *) base;
+  size_t i;
+  struct bintime bt;
+  struct timespec ts;
+
+  printf("=== atomic store release and load acquire test case ===\n");
+
+  for (i = 0; i < active_workers; ++i) {
+    bt = sbttobt(ctx->load_change_time[i] - ctx->load_trigger_time);
+    bintime2timespec(&bt, &ts);
+    printf(
+      "processor %zu delta %lins, load count %i\n",
+      i,
+      ts.tv_nsec,
+      ctx->load_count[i]
+    );
+  }
+
+  printf("=== atomic read-modify-write test case ===\n");
+
+  for (i = 0; i < active_workers; ++i) {
+    bt = sbttobt(ctx->rmw_change_time[i] - ctx->rmw_trigger_time);
+    bintime2timespec(&bt, &ts);
+    printf(
+      "processor %zu delta %lins, read-modify-write count %i\n",
+      i,
+      ts.tv_nsec,
+      ctx->rmw_count[i]
+    );
+  }
+}
+
 static const rtems_test_parallel_job test_jobs[] = {
   {
     .init = test_atomic_add_init,
@@ -435,7 +600,11 @@ static const rtems_test_parallel_job test_jobs[] = {
     .init = test_atomic_fence_init,
     .body = test_atomic_fence_body,
     .fini = test_atomic_fence_fini
-  },
+  }, {
+    .init = test_atomic_store_load_rmw_init,
+    .body = test_atomic_store_load_rmw_body,
+    .fini = test_atomic_store_load_rmw_fini
+  }
 };
 
 static void setup_worker(
@@ -471,6 +640,8 @@ static void Init(rtems_task_argument arg)
 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
 #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
 
+#define CONFIGURE_MICROSECONDS_PER_TICK (MS_PER_TICK * 1000)
+
 #define CONFIGURE_SMP_APPLICATION
 
 #define CONFIGURE_SMP_MAXIMUM_PROCESSORS CPU_COUNT
diff --git a/testsuites/smptests/smpatomic01/smpatomic01.scn b/testsuites/smptests/smpatomic01/smpatomic01.scn
index 89b1980..f3de7c6 100644
--- a/testsuites/smptests/smpatomic01/smpatomic01.scn
+++ b/testsuites/smptests/smpatomic01/smpatomic01.scn
@@ -1,24 +1,184 @@
-*** TEST SMPATOMIC 1 ***
+*** BEGIN OF TEST SMPATOMIC 1 ***
 === atomic add test case ===
-worker 0 value: 16686
-worker 1 value: 36405
-atomic value: expected = 53091, actual = 53091
+worker 0 value: 68020
+worker 1 value: 355745
+worker 2 value: 341230
+worker 3 value: 395115
+worker 4 value: 341233
+worker 5 value: 352026
+worker 6 value: 381492
+worker 7 value: 357940
+worker 8 value: 422258
+worker 9 value: 244645
+worker 10 value: 246474
+worker 11 value: 197385
+worker 12 value: 256213
+worker 13 value: 233617
+worker 14 value: 234606
+worker 15 value: 260702
+worker 16 value: 214706
+worker 17 value: 86201
+worker 18 value: 104268
+worker 19 value: 67940
+worker 20 value: 68509
+worker 21 value: 98021
+worker 22 value: 66668
+worker 23 value: 87962
+atomic value: expected = 5482976, actual = 5482976
 === atomic flag test case ===
-worker 0 value: 5588
-worker 1 value: 16019
-atomic value: expected = 21607, actual = 21607
+worker 0 value: 90301
+worker 1 value: 90507
+worker 2 value: 91048
+worker 3 value: 90930
+worker 4 value: 91129
+worker 5 value: 90994
+worker 6 value: 91677
+worker 7 value: 91086
+worker 8 value: 90729
+worker 9 value: 90540
+worker 10 value: 91358
+worker 11 value: 90859
+worker 12 value: 90954
+worker 13 value: 90816
+worker 14 value: 91052
+worker 15 value: 90994
+worker 16 value: 90961
+worker 17 value: 89741
+worker 18 value: 90144
+worker 19 value: 90270
+worker 20 value: 90301
+worker 21 value: 90054
+worker 22 value: 89782
+worker 23 value: 90108
+atomic value: expected = 2176335, actual = 2176335
 === atomic sub test case ===
-worker 0 value: 4294950967
-worker 1 value: 4294930886
-atomic value: expected = 4294914557, actual = 4294914557
+worker 0 value: 4294821032
+worker 1 value: 4294618821
+worker 2 value: 4294631020
+worker 3 value: 4294597642
+worker 4 value: 4294626165
+worker 5 value: 4294629962
+worker 6 value: 4294601673
+worker 7 value: 4294668647
+worker 8 value: 4294687608
+worker 9 value: 4294691802
+worker 10 value: 4294770759
+worker 11 value: 4294700436
+worker 12 value: 4294715096
+worker 13 value: 4294716993
+worker 14 value: 4294708426
+worker 15 value: 4294725595
+worker 16 value: 4294732565
+worker 17 value: 4294893135
+worker 18 value: 4294857801
+worker 19 value: 4294892291
+worker 20 value: 4294874959
+worker 21 value: 4294839944
+worker 22 value: 4294874753
+worker 23 value: 4294875135
+atomic value: expected = 4289504452, actual = 4289504452
 === atomic compare exchange test case ===
-worker 0 value: 2950
-worker 1 value: 22456
-atomic value: expected = 25406, actual = 25406
+worker 0 value: 121131
+worker 1 value: 134839
+worker 2 value: 139422
+worker 3 value: 123158
+worker 4 value: 122908
+worker 5 value: 134536
+worker 6 value: 134554
+worker 7 value: 133142
+worker 8 value: 129816
+worker 9 value: 133474
+worker 10 value: 129722
+worker 11 value: 140019
+worker 12 value: 129180
+worker 13 value: 122164
+worker 14 value: 135158
+worker 15 value: 126391
+worker 16 value: 132336
+worker 17 value: 123469
+worker 18 value: 122731
+worker 19 value: 124443
+worker 20 value: 125119
+worker 21 value: 121813
+worker 22 value: 123291
+worker 23 value: 121235
+atomic value: expected = 3084051, actual = 3084051
 === atomic or/and test case ===
-worker 0 value: 1
+worker 0 value: 0
 worker 1 value: 0
-atomic value: expected = 1, actual = 1
+worker 2 value: 4
+worker 3 value: 8
+worker 4 value: 0
+worker 5 value: 32
+worker 6 value: 64
+worker 7 value: 0
+worker 8 value: 0
+worker 9 value: 512
+worker 10 value: 0
+worker 11 value: 0
+worker 12 value: 0
+worker 13 value: 8192
+worker 14 value: 16384
+worker 15 value: 0
+worker 16 value: 0
+worker 17 value: 131072
+worker 18 value: 0
+worker 19 value: 524288
+worker 20 value: 1048576
+worker 21 value: 2097152
+worker 22 value: 0
+worker 23 value: 8388608
+atomic value: expected = 12214892, actual = 12214892
 === atomic fence test case ===
-normal value = 10759507, second value = 10759507
+normal value = 10931635, second value = 10931635
+=== atomic store release and load acquire test case ===
+processor 0 delta 1040ns, load count 0
+processor 1 delta 1573ns, load count 59
+processor 2 delta 1840ns, load count 21
+processor 3 delta 1307ns, load count 71
+processor 4 delta 1440ns, load count 45
+processor 5 delta 1973ns, load count 0
+processor 6 delta 1173ns, load count 84
+processor 7 delta 1707ns, load count 34
+processor 8 delta 1867ns, load count 39
+processor 9 delta 1360ns, load count 84
+processor 10 delta 1227ns, load count 0
+processor 11 delta 1760ns, load count 51
+processor 12 delta 1493ns, load count 13
+processor 13 delta 2000ns, load count 64
+processor 14 delta 2133ns, load count 77
+processor 15 delta 1627ns, load count 26
+processor 16 delta 2240ns, load count 41
+processor 17 delta 1733ns, load count 0
+processor 18 delta 2000ns, load count 29
+processor 19 delta 1467ns, load count 74
+processor 20 delta 1600ns, load count 16
+processor 21 delta 1200ns, load count 66
+processor 22 delta 1867ns, load count 3
+processor 23 delta 1333ns, load count 53
+=== atomic read-modify-write test case ===
+processor 0 delta 1067ns, read-modify-write count 0
+processor 1 delta 3921ns, read-modify-write count 0
+processor 2 delta 3067ns, read-modify-write count 0
+processor 3 delta 1200ns, read-modify-write count 0
+processor 4 delta 3600ns, read-modify-write count 0
+processor 5 delta 3334ns, read-modify-write count 0
+processor 6 delta 1334ns, read-modify-write count 0
+processor 7 delta 2187ns, read-modify-write count 0
+processor 8 delta 1147ns, read-modify-write count 0
+processor 9 delta 3947ns, read-modify-write count 0
+processor 10 delta 2321ns, read-modify-write count 0
+processor 11 delta 3734ns, read-modify-write count 0
+processor 12 delta 2827ns, read-modify-write count 1
+processor 13 delta 2481ns, read-modify-write count 0
+processor 14 delta 1254ns, read-modify-write count 0
+processor 15 delta 2667ns, read-modify-write count 0
+processor 16 delta 3467ns, read-modify-write count 0
+processor 17 delta 2054ns, read-modify-write count 0
+processor 18 delta 1707ns, read-modify-write count 1
+processor 19 delta 1894ns, read-modify-write count 0
+processor 20 delta 2934ns, read-modify-write count 0
+processor 21 delta 1547ns, read-modify-write count 0
+processor 22 delta 1361ns, read-modify-write count 0
+processor 23 delta 3200ns, read-modify-write count 0
 *** END OF TEST SMPATOMIC 1 ***



More information about the vc mailing list