Changeset 4fe0e97f in rtems for testsuites/smptests


Ignore:
Timestamp:
Jun 30, 2016, 7:50:41 AM (4 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
4280dff7
Parents:
729cf694
git-author:
Sebastian Huber <sebastian.huber@…> (06/30/16 07:50:41)
git-committer:
Sebastian Huber <sebastian.huber@…> (06/30/16 07:54:41)
Message:

smptests/smpstrongapa01: Add test cases

File:
1 edited

Legend:

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

    r729cf694 r4fe0e97f  
    1919#include "tmacros.h"
    2020
     21#include <rtems/score/threadimpl.h>
     22
    2123const char rtems_test_name[] = "SMPSTRONGAPA 1";
    2224
     25#define CPU_COUNT 4
     26
     27#define TASK_COUNT (3 * CPU_COUNT)
     28
     29#define P(i) (UINT32_C(2) + i)
     30
     31#define ALL ((UINT32_C(1) << CPU_COUNT) - 1)
     32
     33#define IDLE UINT8_C(255)
     34
     35#define NAME rtems_build_name('S', 'A', 'P', 'A')
     36
     37typedef struct {
     38  enum {
     39    KIND_RESET,
     40    KIND_SET_PRIORITY,
     41    KIND_SET_AFFINITY,
     42    KIND_BLOCK,
     43    KIND_UNBLOCK
     44  } kind;
     45
     46  size_t index;
     47
     48  struct {
     49    rtems_task_priority priority;
     50    uint32_t cpu_set;
     51  } data;
     52
     53  uint8_t expected_cpu_allocations[CPU_COUNT];
     54} test_action;
     55
     56typedef struct {
     57  rtems_id timer_id;
     58  rtems_id master_id;
     59  rtems_id task_ids[TASK_COUNT];
     60  size_t action_index;
     61} test_context;
     62
     63#define RESET \
     64  { \
     65    KIND_RESET, \
     66    0, \
     67    { 0 }, \
     68    { IDLE, IDLE, IDLE, IDLE } \
     69  }
     70
     71#define SET_PRIORITY(index, prio, cpu0, cpu1, cpu2, cpu3) \
     72  { \
     73    KIND_SET_PRIORITY, \
     74    index, \
     75    { .priority = prio }, \
     76    { cpu0, cpu1, cpu2, cpu3 } \
     77  }
     78
     79#define SET_AFFINITY(index, aff, cpu0, cpu1, cpu2, cpu3) \
     80  { \
     81    KIND_SET_AFFINITY, \
     82    index, \
     83    { .cpu_set = aff }, \
     84    { cpu0, cpu1, cpu2, cpu3 } \
     85  }
     86
     87#define BLOCK(index, cpu0, cpu1, cpu2, cpu3) \
     88  { \
     89    KIND_BLOCK, \
     90    index, \
     91    { 0 }, \
     92    { cpu0, cpu1, cpu2, cpu3 } \
     93  }
     94
     95#define UNBLOCK(index, cpu0, cpu1, cpu2, cpu3) \
     96  { \
     97    KIND_UNBLOCK, \
     98    index, \
     99    { 0 }, \
     100    { cpu0, cpu1, cpu2, cpu3 } \
     101  }
     102
     103static const test_action test_actions[] = {
     104  RESET,
     105  UNBLOCK(      0,           0, IDLE, IDLE, IDLE),
     106  UNBLOCK(      1,           0,    1, IDLE, IDLE),
     107  UNBLOCK(      2,           0,    1,    2, IDLE),
     108  UNBLOCK(      3,           0,    1,    2,    3),
     109  UNBLOCK(      5,           0,    1,    2,    3),
     110  SET_PRIORITY( 3,  P(4),    0,    1,    2,    3),
     111  SET_PRIORITY( 5,  P(3),    0,    1,    2,    5),
     112  BLOCK(        5,           0,    1,    2,    3),
     113  SET_AFFINITY( 5,   ALL,    0,    1,    2,    3),
     114  RESET,
     115  UNBLOCK(      0,           0, IDLE, IDLE, IDLE),
     116  RESET
     117};
     118
     119static test_context test_instance;
     120
     121static void set_priority(rtems_id id, rtems_task_priority prio)
     122{
     123  rtems_status_code sc;
     124
     125  sc = rtems_task_set_priority(id, prio, &prio);
     126  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     127}
     128
     129static void set_affinity(rtems_id id, uint32_t cpu_set_32)
     130{
     131  rtems_status_code sc;
     132  cpu_set_t cpu_set;
     133  size_t i;
     134
     135  CPU_ZERO(&cpu_set);
     136
     137  for (i = 0; i < CPU_COUNT; ++i) {
     138    uint32_t one;
     139
     140    one = 1;
     141
     142    if ((cpu_set_32 & (one << i)) != 0) {
     143      CPU_SET(i, &cpu_set);
     144    }
     145  }
     146
     147  sc = rtems_task_set_affinity(id, sizeof(cpu_set), &cpu_set);
     148  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     149}
     150
     151static void reset(test_context *ctx)
     152{
     153  rtems_status_code sc;
     154  size_t i;
     155
     156  for (i = CPU_COUNT; i < TASK_COUNT; ++i) {
     157    set_priority(ctx->task_ids[i], P(i));
     158    set_affinity(ctx->task_ids[i], ALL);
     159
     160    sc = rtems_task_suspend(ctx->task_ids[i]);
     161    rtems_test_assert(sc == RTEMS_SUCCESSFUL || sc == RTEMS_ALREADY_SUSPENDED);
     162  }
     163
     164  for (i = 0; i < CPU_COUNT; ++i) {
     165    set_priority(ctx->task_ids[i], P(i));
     166
     167    sc = rtems_task_resume(ctx->task_ids[i]);
     168    rtems_test_assert(sc == RTEMS_SUCCESSFUL || sc == RTEMS_INCORRECT_STATE);
     169  }
     170
     171  /* Order the idle threads explicitly */
     172  for (i = 0; i < CPU_COUNT; ++i) {
     173    const Per_CPU_Control *c;
     174    const Thread_Control *h;
     175
     176    c = _Per_CPU_Get_by_index(CPU_COUNT - 1 - i);
     177    h = c->heir;
     178
     179    sc = rtems_task_suspend(h->Object.id);
     180    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     181  }
     182}
     183
     184static void check_cpu_allocations(test_context *ctx, const test_action *action)
     185{
     186  size_t i;
     187
     188  for (i = 0; i < CPU_COUNT; ++i) {
     189    size_t e;
     190    const Per_CPU_Control *c;
     191    const Thread_Control *h;
     192
     193    e = action->expected_cpu_allocations[i];
     194    c = _Per_CPU_Get_by_index(i);
     195    h = c->heir;
     196
     197    if (e != IDLE) {
     198      rtems_test_assert(h->Object.id == ctx->task_ids[e]);
     199    } else {
     200      rtems_test_assert(h->Start.Entry.adaptor == _Thread_Entry_adaptor_idle);
     201    }
     202  }
     203}
     204
     205/*
     206 * Use a timer to execute the actions, since it runs with thread dispatching
     207 * disabled.  This is necessary to check the expected processor allocations.
     208 */
     209static void timer(rtems_id id, void *arg)
     210{
     211  test_context *ctx;
     212  rtems_status_code sc;
     213  size_t i;
     214
     215  ctx = arg;
     216  i = ctx->action_index;
     217
     218  if (i == 0) {
     219    sc = rtems_task_suspend(ctx->master_id);
     220    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     221  }
     222
     223  if (i < RTEMS_ARRAY_SIZE(test_actions)) {
     224    const test_action *action = &test_actions[i];
     225    rtems_id task;
     226
     227    ctx->action_index = i + 1;
     228
     229    task = ctx->task_ids[action->index];
     230
     231    switch (action->kind) {
     232      case KIND_SET_PRIORITY:
     233        set_priority(task, action->data.priority);
     234        break;
     235      case KIND_SET_AFFINITY:
     236        set_affinity(task, action->data.cpu_set);
     237        break;
     238      case KIND_BLOCK:
     239        sc = rtems_task_suspend(task);
     240        rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     241        break;
     242      case KIND_UNBLOCK:
     243        sc = rtems_task_resume(task);
     244        rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     245        break;
     246      default:
     247        rtems_test_assert(action->kind == KIND_RESET);
     248        reset(ctx);
     249        break;
     250    }
     251
     252    check_cpu_allocations(ctx, action);
     253
     254    sc = rtems_timer_reset(id);
     255    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     256  } else {
     257    sc = rtems_task_resume(ctx->master_id);
     258    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     259
     260    sc = rtems_event_transient_send(ctx->master_id);
     261    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     262  }
     263}
     264
     265static void do_nothing_task(rtems_task_argument arg)
     266{
     267  (void) arg;
     268
     269  while (true) {
     270    /* Do nothing */
     271  }
     272}
     273
    23274static void test(void)
    24275{
     276  test_context *ctx;
     277  rtems_status_code sc;
     278  size_t i;
     279
     280  ctx = &test_instance;
     281
     282  ctx->master_id = rtems_task_self();
     283
     284  for (i = 0; i < TASK_COUNT; ++i) {
     285    sc = rtems_task_create(
     286      NAME,
     287      P(i),
     288      RTEMS_MINIMUM_STACK_SIZE,
     289      RTEMS_DEFAULT_MODES,
     290      RTEMS_DEFAULT_ATTRIBUTES,
     291      &ctx->task_ids[i]
     292    );
     293    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     294
     295    sc = rtems_task_start(ctx->task_ids[i], do_nothing_task, 0);
     296    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     297  }
     298
     299  sc = rtems_timer_create(NAME, &ctx->timer_id);
     300  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     301
     302  sc = rtems_timer_fire_after(ctx->timer_id, 1, timer, ctx);
     303  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     304
     305  sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
     306  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     307
     308  for (i = 0; i < TASK_COUNT; ++i) {
     309    sc = rtems_task_delete(ctx->task_ids[i]);
     310    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     311  }
     312
     313  sc = rtems_timer_delete(ctx->timer_id);
     314  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    25315}
    26316
     
    29319  TEST_BEGIN();
    30320
    31   test();
     321  if (rtems_get_processor_count() == CPU_COUNT) {
     322    test();
     323  } else {
     324    puts("warning: wrong processor count to run the test");
     325  }
    32326
    33327  TEST_END();
     
    35329}
    36330
     331#define CONFIGURE_MICROSECONDS_PER_TICK 1000
     332
    37333#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
    38334#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
    39335
    40 #define CONFIGURE_MAXIMUM_TASKS 1
     336#define CONFIGURE_MAXIMUM_TASKS (1 + TASK_COUNT)
     337#define CONFIGURE_MAXIMUM_TIMERS 1
    41338
    42339#define CONFIGURE_SMP_APPLICATION
    43340
    44 #define CONFIGURE_SMP_MAXIMUM_PROCESSORS 2
     341#define CONFIGURE_SMP_MAXIMUM_PROCESSORS CPU_COUNT
    45342
    46343#define CONFIGURE_SCHEDULER_STRONG_APA
Note: See TracChangeset for help on using the changeset viewer.