forked from Imagelibrary/rtems
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.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ***
|
||||
|
||||
Reference in New Issue
Block a user