Index: testsuites/smptests/smpatomic01/init.c
===================================================================
--- testsuites/smptests/smpatomic01/init.c	(revision 8d296cd54e51d2fe1f6bf5344cca70c822b04568)
+++ testsuites/smptests/smpatomic01/init.c	(revision a9cc6a84c50c7745155192ca8fda2ba36e43dd69)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2013-2015 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2013, 2016 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
@@ -20,5 +20,7 @@
 
 #include <rtems/score/atomic.h>
+#include <rtems/score/smpbarrier.h>
 #include <rtems.h>
+#include <rtems/bsd.h>
 #include <rtems/test.h>
 #include <limits.h>
@@ -28,4 +30,6 @@
 
 const char rtems_test_name[] = "SMPATOMIC 1";
+
+#define MS_PER_TICK 10
 
 #define MASTER_PRIORITY 1
@@ -43,4 +47,12 @@
   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;
 
@@ -409,4 +421,157 @@
     ctx->second_value
   );
+}
+
+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]
+    );
+  }
 }
 
@@ -436,5 +601,9 @@
     .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
+  }
 };
 
@@ -472,4 +641,6 @@
 #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
 
+#define CONFIGURE_MICROSECONDS_PER_TICK (MS_PER_TICK * 1000)
+
 #define CONFIGURE_SMP_APPLICATION
 
