Ignore:
Timestamp:
Mar 5, 2015, 8:06:44 AM (5 years ago)
Author:
Alexander Krutwig <alexander.krutwig@…>
Branches:
4.11, 5, master
Children:
5b5d2fd4
Parents:
51acbdc
git-author:
Alexander Krutwig <alexander.krutwig@…> (03/05/15 08:06:44)
git-committer:
Sebastian Huber <sebastian.huber@…> (03/05/15 08:12:14)
Message:

tests: Refactor parallel test execution

File:
1 edited

Legend:

Unmodified
Added
Removed
  • testsuites/smptests/smpatomic01/init.c

    r51acbdc r7f577d3  
    11/*
    2  * Copyright (c) 2013-2014 embedded brains GmbH.  All rights reserved.
     2 * Copyright (c) 2013-2015 embedded brains GmbH.  All rights reserved.
    33 *
    44 *  embedded brains GmbH
     
    2020
    2121#include <rtems/score/atomic.h>
    22 #include <rtems/score/smpbarrier.h>
    2322#include <rtems.h>
     23#include <rtems/test.h>
    2424#include <limits.h>
    2525#include <string.h>
     
    3636
    3737typedef struct {
    38   Atomic_Ulong stop;
    39   SMP_barrier_Control barrier;
    40   size_t worker_count;
    41   rtems_id stop_worker_timer_id;
     38  rtems_test_parallel_context base;
    4239  Atomic_Uint atomic_int_value;
    4340  Atomic_Ulong atomic_value;
     
    4744  unsigned long second_value;
    4845  Atomic_Flag global_flag;
    49 } test_context;
    50 
    51 typedef struct {
    52   void (*init)(test_context *ctx);
    53   void (*body)(test_context *ctx, size_t worker_index);
    54   void (*fini)(test_context *ctx);
    55 } test_case;
    56 
    57 static test_context test_instance = {
    58   .stop = ATOMIC_INITIALIZER_ULONG(0),
    59   .barrier = SMP_BARRIER_CONTROL_INITIALIZER
    60 };
    61 
    62 static bool stop(test_context *ctx)
    63 {
    64   return _Atomic_Load_ulong(&ctx->stop, ATOMIC_ORDER_RELAXED) != 0;
    65 }
    66 
    67 static bool is_master_worker(size_t worker_index)
    68 {
    69   return worker_index == 0;
     46} smpatomic01_context;
     47
     48static smpatomic01_context test_instance;
     49
     50static rtems_interval test_duration(void)
     51{
     52  return rtems_clock_get_ticks_per_second();
    7053}
    7154
    7255static void test_fini(
    73   test_context *ctx,
     56  smpatomic01_context *ctx,
    7457  const char *test,
    7558  bool atomic
     
    8265  printf("=== atomic %s test case ===\n", test);
    8366
    84   for (worker_index = 0; worker_index < ctx->worker_count; ++worker_index) {
     67  for (
     68    worker_index = 0;
     69    worker_index < ctx->base.worker_count;
     70    ++worker_index
     71  ) {
    8572    unsigned long worker_value = ctx->per_worker_value[worker_index];
    8673
     
    10996}
    11097
    111 static void test_atomic_add_init(test_context *ctx)
    112 {
     98
     99static rtems_interval test_atomic_add_init(
     100  rtems_test_parallel_context *base,
     101  void *arg
     102)
     103{
     104  smpatomic01_context *ctx = (smpatomic01_context *) base;
     105
    113106  _Atomic_Init_ulong(&ctx->atomic_value, 0);
    114 }
    115 
    116 static void test_atomic_add_body(test_context *ctx, size_t worker_index)
    117 {
     107
     108  return test_duration();
     109}
     110
     111static void test_atomic_add_body(
     112  rtems_test_parallel_context *base,
     113  void *arg,
     114  size_t worker_index
     115)
     116{
     117  smpatomic01_context *ctx = (smpatomic01_context *) base;
    118118  unsigned long counter = 0;
    119119
    120   while (!stop(ctx)) {
     120  while (!rtems_test_parallel_stop_job(&ctx->base)) {
    121121    ++counter;
    122122    _Atomic_Fetch_add_ulong(&ctx->atomic_value, 1, ATOMIC_ORDER_RELAXED);
     
    126126}
    127127
    128 static void test_atomic_add_fini(test_context *ctx)
    129 {
     128static void test_atomic_add_fini(rtems_test_parallel_context *base, void *arg)
     129{
     130  smpatomic01_context *ctx = (smpatomic01_context *) base;
     131
    130132  test_fini(ctx, "add", true);
    131133}
    132134
    133 static void test_atomic_flag_init(test_context *ctx)
    134 {
     135static rtems_interval test_atomic_flag_init(
     136  rtems_test_parallel_context *base,
     137  void *arg
     138)
     139{
     140  smpatomic01_context *ctx = (smpatomic01_context *) base;
     141
    135142  _Atomic_Flag_clear(&ctx->global_flag, ATOMIC_ORDER_RELEASE);
    136143  ctx->normal_value = 0;
    137 }
    138 
    139 static void test_atomic_flag_body(test_context *ctx, size_t worker_index)
    140 {
     144
     145  return test_duration();
     146}
     147
     148static void test_atomic_flag_body(
     149  rtems_test_parallel_context *base,
     150  void *arg,
     151  size_t worker_index
     152)
     153{
     154  smpatomic01_context *ctx = (smpatomic01_context *) base;
    141155  unsigned long counter = 0;
    142156
    143   while (!stop(ctx)) {
     157  while (!rtems_test_parallel_stop_job(&ctx->base)) {
    144158    while (_Atomic_Flag_test_and_set(&ctx->global_flag, ATOMIC_ORDER_ACQUIRE)) {
    145159      /* Wait */
     
    155169}
    156170
    157 static void test_atomic_flag_fini(test_context *ctx)
    158 {
     171static void test_atomic_flag_fini(rtems_test_parallel_context *base, void *arg)
     172{
     173  smpatomic01_context *ctx = (smpatomic01_context *) base;
     174
    159175  test_fini(ctx, "flag", false);
    160176}
    161177
    162 static void test_atomic_sub_init(test_context *ctx)
    163 {
     178static rtems_interval test_atomic_sub_init(
     179  rtems_test_parallel_context *base,
     180  void *arg
     181)
     182{
     183  smpatomic01_context *ctx = (smpatomic01_context *) base;
     184
    164185  _Atomic_Init_ulong(&ctx->atomic_value, 0);
    165 }
    166 
    167 static void test_atomic_sub_body(test_context *ctx, size_t worker_index)
    168 {
     186
     187  return test_duration();
     188}
     189
     190static void test_atomic_sub_body(
     191  rtems_test_parallel_context *base,
     192  void *arg,
     193  size_t worker_index
     194)
     195{
     196  smpatomic01_context *ctx = (smpatomic01_context *) base;
    169197  unsigned long counter = 0;
    170198
    171   while (!stop(ctx)) {
     199  while (!rtems_test_parallel_stop_job(&ctx->base)) {
    172200    --counter;
    173201    _Atomic_Fetch_sub_ulong(&ctx->atomic_value, 1, ATOMIC_ORDER_RELAXED);
     
    177205}
    178206
    179 static void test_atomic_sub_fini(test_context *ctx)
    180 {
     207static void test_atomic_sub_fini(rtems_test_parallel_context *base, void *arg)
     208{
     209  smpatomic01_context *ctx = (smpatomic01_context *) base;
     210
    181211  test_fini(ctx, "sub", true);
    182212}
    183213
    184 static void test_atomic_compare_exchange_init(test_context *ctx)
    185 {
     214static rtems_interval test_atomic_compare_exchange_init(
     215  rtems_test_parallel_context *base,
     216  void *arg
     217)
     218{
     219  smpatomic01_context *ctx = (smpatomic01_context *) base;
     220
    186221  _Atomic_Init_ulong(&ctx->atomic_value, 0);
    187222  ctx->normal_value = 0;
    188 }
    189 
    190 static void test_atomic_compare_exchange_body(test_context *ctx, size_t worker_index)
    191 {
     223
     224  return test_duration();
     225}
     226
     227static void test_atomic_compare_exchange_body(
     228  rtems_test_parallel_context *base,
     229  void *arg,
     230  size_t worker_index
     231)
     232{
     233  smpatomic01_context *ctx = (smpatomic01_context *) base;
    192234  unsigned long counter = 0;
    193235
    194   while (!stop(ctx)) {
     236  while (!rtems_test_parallel_stop_job(&ctx->base)) {
    195237    bool success;
    196238
     
    216258}
    217259
    218 static void test_atomic_compare_exchange_fini(test_context *ctx)
    219 {
     260static void test_atomic_compare_exchange_fini(
     261  rtems_test_parallel_context *base,
     262  void *arg
     263)
     264{
     265  smpatomic01_context *ctx = (smpatomic01_context *) base;
     266
    220267  test_fini(ctx, "compare exchange", false);
    221268}
    222269
    223 static void test_atomic_or_and_init(test_context *ctx)
    224 {
     270static rtems_interval test_atomic_or_and_init(
     271  rtems_test_parallel_context *base,
     272  void *arg
     273)
     274{
     275  smpatomic01_context *ctx = (smpatomic01_context *) base;
     276
    225277  _Atomic_Init_ulong(&ctx->atomic_value, 0);
    226 }
    227 
    228 static void test_atomic_or_and_body(test_context *ctx, size_t worker_index)
    229 {
     278
     279  return test_duration();
     280}
     281
     282static void test_atomic_or_and_body(
     283  rtems_test_parallel_context *base,
     284  void *arg,
     285  size_t worker_index
     286)
     287{
     288  smpatomic01_context *ctx = (smpatomic01_context *) base;
    230289  unsigned long the_bit = 1UL << worker_index;
    231290  unsigned long current_bit = 0;
    232291
    233   while (!stop(ctx)) {
     292  while (!rtems_test_parallel_stop_job(&ctx->base)) {
    234293    unsigned long previous;
    235294
     
    256315}
    257316
    258 static void test_atomic_or_and_fini(test_context *ctx)
    259 {
     317static void test_atomic_or_and_fini(
     318  rtems_test_parallel_context *base,
     319  void *arg
     320)
     321{
     322  smpatomic01_context *ctx = (smpatomic01_context *) base;
     323
    260324  test_fini(ctx, "or/and", true);
    261325}
    262326
    263 static void test_atomic_fence_init(test_context *ctx)
    264 {
     327static rtems_interval test_atomic_fence_init(
     328  rtems_test_parallel_context *base,
     329  void *arg
     330)
     331{
     332  smpatomic01_context *ctx = (smpatomic01_context *) base;
     333
    265334  ctx->normal_value = 0;
    266335  ctx->second_value = 0;
    267336  _Atomic_Fence(ATOMIC_ORDER_RELEASE);
    268 }
    269 
    270 static void test_atomic_fence_body(test_context *ctx, size_t worker_index)
    271 {
    272   if (is_master_worker(worker_index)) {
     337
     338  return test_duration();
     339}
     340
     341static void test_atomic_fence_body(
     342  rtems_test_parallel_context *base,
     343  void *arg,
     344  size_t worker_index
     345)
     346{
     347  smpatomic01_context *ctx = (smpatomic01_context *) base;
     348
     349  if (rtems_test_parallel_is_master_worker(worker_index)) {
    273350    unsigned long counter = 0;
    274351
    275     while (!stop(ctx)) {
     352    while (!rtems_test_parallel_stop_job(&ctx->base)) {
    276353      ++counter;
    277354      ctx->normal_value = counter;
     
    280357    }
    281358  } else {
    282     while (!stop(ctx)) {
     359    while (!rtems_test_parallel_stop_job(&ctx->base)) {
    283360      unsigned long n;
    284361      unsigned long s;
     
    293370}
    294371
    295 static void test_atomic_fence_fini(test_context *ctx)
    296 {
     372static void test_atomic_fence_fini(rtems_test_parallel_context *base, void *arg)
     373{
     374  smpatomic01_context *ctx = (smpatomic01_context *) base;
     375
    297376  printf(
    298377    "=== atomic fence test case ===\n"
     
    303382}
    304383
    305 static const test_case test_cases[] = {
     384static const rtems_test_parallel_job test_jobs[] = {
    306385  {
    307386    test_atomic_add_init,
     
    331410};
    332411
    333 #define TEST_COUNT RTEMS_ARRAY_SIZE(test_cases)
    334 
    335 static void stop_worker_timer(rtems_id timer_id, void *arg)
    336 {
    337   test_context *ctx = arg;
    338 
    339   _Atomic_Store_ulong(&ctx->stop, 1, ATOMIC_ORDER_RELAXED);
    340 }
    341 
    342 static void start_worker_stop_timer(test_context *ctx)
    343 {
    344   rtems_status_code sc;
    345 
    346   _Atomic_Store_ulong(&ctx->stop, 0, ATOMIC_ORDER_RELEASE);
    347 
    348   sc = rtems_timer_fire_after(
    349     ctx->stop_worker_timer_id,
    350     rtems_clock_get_ticks_per_second(),
    351     stop_worker_timer,
    352     ctx
     412static void Init(rtems_task_argument arg)
     413{
     414  smpatomic01_context *ctx = &test_instance;
     415
     416  TEST_BEGIN();
     417
     418  rtems_test_parallel(
     419    &ctx->base,
     420    WORKER_PRIORITY,
     421    &test_jobs[0],
     422    RTEMS_ARRAY_SIZE(test_jobs)
    353423  );
    354   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    355 }
    356 
    357 static void run_tests(test_context *ctx, size_t worker_index)
    358 {
    359   SMP_barrier_State bs = SMP_BARRIER_STATE_INITIALIZER;
    360   size_t test;
    361 
    362   for (test = 0; test < TEST_COUNT; ++test) {
    363     const test_case *tc = &test_cases[test];
    364 
    365     if (is_master_worker(worker_index)) {
    366       start_worker_stop_timer(ctx);
    367       (*tc->init)(ctx);
    368     }
    369 
    370     _SMP_barrier_Wait(&ctx->barrier, &bs, ctx->worker_count);
    371 
    372     (*tc->body)(ctx, worker_index);
    373 
    374     _SMP_barrier_Wait(&ctx->barrier, &bs, ctx->worker_count);
    375 
    376     if (is_master_worker(worker_index)) {
    377       (*tc->fini)(ctx);
    378     }
    379   }
    380 }
    381 
    382 static void worker_task(size_t worker_index)
    383 {
    384   test_context *ctx = &test_instance;
    385 
    386   run_tests(ctx, worker_index);
    387 
    388   (void) rtems_task_suspend(RTEMS_SELF);
    389   rtems_test_assert(0);
    390 }
    391 
    392 static void test(void)
    393 {
    394   test_context *ctx = &test_instance;
    395   rtems_status_code sc;
    396   size_t worker_index;
    397 
    398   ctx->worker_count = rtems_get_processor_count();
    399 
    400   sc = rtems_timer_create(
    401     rtems_build_name('S', 'T', 'O', 'P'),
    402     &ctx->stop_worker_timer_id
    403   );
    404   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    405 
    406   for (worker_index = 1; worker_index < ctx->worker_count; ++worker_index) {
    407     rtems_id worker_id;
    408 
    409     sc = rtems_task_create(
    410       rtems_build_name('W', 'O', 'R', 'K'),
    411       WORKER_PRIORITY,
    412       RTEMS_MINIMUM_STACK_SIZE,
    413       RTEMS_DEFAULT_MODES,
    414       RTEMS_DEFAULT_ATTRIBUTES,
    415       &worker_id
    416     );
    417     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    418 
    419     sc = rtems_task_start(worker_id, worker_task, worker_index);
    420     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    421   }
    422 
    423   run_tests(ctx, 0);
    424 }
    425 
    426 static void Init(rtems_task_argument arg)
    427 {
    428   TEST_BEGIN();
    429 
    430   test();
    431424
    432425  TEST_END();
Note: See TracChangeset for help on using the changeset viewer.