summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-06-07 15:26:52 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-06-07 15:28:57 +0200
commitcc8bb9e3376ce1d36ec9da06501e62f45c9b3b3b (patch)
tree032bce8d61d1e900fba2c94683d31db311c784bd
parentrtems: Simplify rtems_semaphore_create() (diff)
downloadrtems-cc8bb9e3376ce1d36ec9da06501e62f45c9b3b3b.tar.bz2
smptests/smpatomic01: Add seqlock test case
-rw-r--r--testsuites/smptests/smpatomic01/init.c185
-rw-r--r--testsuites/smptests/smpatomic01/smpatomic01.scn50
2 files changed, 235 insertions, 0 deletions
diff --git a/testsuites/smptests/smpatomic01/init.c b/testsuites/smptests/smpatomic01/init.c
index 673ff28d74..00a0cb5392 100644
--- a/testsuites/smptests/smpatomic01/init.c
+++ b/testsuites/smptests/smpatomic01/init.c
@@ -575,6 +575,183 @@ static void test_atomic_store_load_rmw_fini(
}
}
+/*
+ * See also Hans-J. Boehm, HP Laboratories,
+ * "Can Seqlocks Get Along With Programming Language Memory Models?",
+ * http://www.hpl.hp.com/techreports/2012/HPL-2012-68.pdf
+ */
+
+static rtems_interval test_seqlock_init(
+ rtems_test_parallel_context *base,
+ void *arg,
+ size_t active_workers
+)
+{
+ smpatomic01_context *ctx = (smpatomic01_context *) base;
+
+ ctx->normal_value = 0;
+ ctx->second_value = 0;
+ _Atomic_Store_ulong(&ctx->atomic_value, 0, ATOMIC_ORDER_RELEASE);
+
+ return test_duration();
+}
+
+static unsigned long seqlock_read(smpatomic01_context *ctx)
+{
+ unsigned long counter = 0;
+
+ while (!rtems_test_parallel_stop_job(&ctx->base)) {
+ unsigned long seq0;
+ unsigned long seq1;
+ unsigned long a;
+ unsigned long b;
+
+ do {
+ seq0 = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_ACQUIRE);
+
+ a = ctx->normal_value;
+ b = ctx->second_value;
+
+ seq1 =
+ _Atomic_Fetch_add_ulong(&ctx->atomic_value, 0, ATOMIC_ORDER_RELEASE);
+ } while (seq0 != seq1 || seq0 % 2 != 0);
+
+ ++counter;
+ rtems_test_assert(a == b);
+ }
+
+ return counter;
+}
+
+static void test_single_writer_seqlock_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;
+ unsigned long counter;
+
+ /*
+ * Use the physical processor index, to observe timing differences introduced
+ * by the system topology.
+ */
+ cpu_self_index = rtems_get_current_processor();
+
+ if (cpu_self_index == 0) {
+ counter = 0;
+
+ while (!rtems_test_parallel_stop_job(&ctx->base)) {
+ unsigned long seq;
+
+ seq = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED);
+ _Atomic_Store_ulong(&ctx->atomic_value, seq + 1, ATOMIC_ORDER_RELAXED);
+ _Atomic_Fence(ATOMIC_ORDER_ACQUIRE);
+
+ ++counter;
+ ctx->normal_value = counter;
+ ctx->second_value = counter;
+
+ _Atomic_Store_ulong(&ctx->atomic_value, seq + 2, ATOMIC_ORDER_RELEASE);
+ }
+ } else {
+ counter = seqlock_read(ctx);
+ }
+
+ ctx->per_worker_value[cpu_self_index] = counter;
+}
+
+static void test_single_writer_seqlock_fini(
+ rtems_test_parallel_context *base,
+ void *arg,
+ size_t active_workers
+)
+{
+ smpatomic01_context *ctx = (smpatomic01_context *) base;
+ size_t i;
+
+ printf("=== single writer seqlock test case ===\n");
+
+ for (i = 0; i < active_workers; ++i) {
+ printf(
+ "processor %zu count %lu\n",
+ i,
+ ctx->per_worker_value[i]
+ );
+ }
+}
+
+static void test_multi_writer_seqlock_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;
+ unsigned long counter;
+
+ /*
+ * Use the physical processor index, to observe timing differences introduced
+ * by the system topology.
+ */
+ cpu_self_index = rtems_get_current_processor();
+
+ if (cpu_self_index % 2 == 0) {
+ counter = 0;
+
+ while (!rtems_test_parallel_stop_job(&ctx->base)) {
+ unsigned long seq;
+
+ do {
+ seq = _Atomic_Load_ulong(&ctx->atomic_value, ATOMIC_ORDER_RELAXED);
+ } while (
+ seq % 2 != 0
+ || !_Atomic_Compare_exchange_ulong(
+ &ctx->atomic_value,
+ &seq,
+ seq + 1,
+ ATOMIC_ORDER_ACQ_REL,
+ ATOMIC_ORDER_RELAXED
+ )
+ );
+
+ ++counter;
+ ctx->normal_value = counter;
+ ctx->second_value = counter;
+
+ _Atomic_Store_ulong(&ctx->atomic_value, seq + 2, ATOMIC_ORDER_RELEASE);
+ }
+ } else {
+ counter = seqlock_read(ctx);
+ }
+
+ ctx->per_worker_value[cpu_self_index] = counter;
+}
+
+static void test_multi_writer_seqlock_fini(
+ rtems_test_parallel_context *base,
+ void *arg,
+ size_t active_workers
+)
+{
+ smpatomic01_context *ctx = (smpatomic01_context *) base;
+ size_t i;
+
+ printf("=== multi writer seqlock test case ===\n");
+
+ for (i = 0; i < active_workers; ++i) {
+ printf(
+ "processor %zu count %lu\n",
+ i,
+ ctx->per_worker_value[i]
+ );
+ }
+}
+
static const rtems_test_parallel_job test_jobs[] = {
{
.init = test_atomic_add_init,
@@ -604,6 +781,14 @@ static const rtems_test_parallel_job test_jobs[] = {
.init = test_atomic_store_load_rmw_init,
.body = test_atomic_store_load_rmw_body,
.fini = test_atomic_store_load_rmw_fini
+ }, {
+ .init = test_seqlock_init,
+ .body = test_single_writer_seqlock_body,
+ .fini = test_single_writer_seqlock_fini
+ }, {
+ .init = test_seqlock_init,
+ .body = test_multi_writer_seqlock_body,
+ .fini = test_multi_writer_seqlock_fini
}
};
diff --git a/testsuites/smptests/smpatomic01/smpatomic01.scn b/testsuites/smptests/smpatomic01/smpatomic01.scn
index f3de7c6a93..01f6ad4844 100644
--- a/testsuites/smptests/smpatomic01/smpatomic01.scn
+++ b/testsuites/smptests/smpatomic01/smpatomic01.scn
@@ -181,4 +181,54 @@ 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
+=== single writer seqlock test case ===
+processor 0 count 2451021
+processor 1 count 1
+processor 2 count 8
+processor 3 count 31
+processor 4 count 52
+processor 5 count 23
+processor 6 count 23
+processor 7 count 49
+processor 8 count 703
+processor 9 count 750
+processor 10 count 684
+processor 11 count 770
+processor 12 count 710
+processor 13 count 691
+processor 14 count 687
+processor 15 count 695
+processor 16 count 774
+processor 17 count 828
+processor 18 count 732
+processor 19 count 719
+processor 20 count 728
+processor 21 count 761
+processor 22 count 685
+processor 23 count 764
+=== multi writer seqlock test case ===
+processor 0 count 124410
+processor 1 count 7865
+processor 2 count 123950
+processor 3 count 7797
+processor 4 count 124253
+processor 5 count 7773
+processor 6 count 124763
+processor 7 count 7817
+processor 8 count 124593
+processor 9 count 7781
+processor 10 count 124647
+processor 11 count 7753
+processor 12 count 124322
+processor 13 count 7692
+processor 14 count 124906
+processor 15 count 7715
+processor 16 count 124568
+processor 17 count 7605
+processor 18 count 125060
+processor 19 count 7908
+processor 20 count 124499
+processor 21 count 7804
+processor 22 count 124538
+processor 23 count 7874
*** END OF TEST SMPATOMIC 1 ***