source: rtems/testsuites/smptests/smpclock01/init.c @ 03c9f24

5
Last change on this file since 03c9f24 was 03c9f24, checked in by Sebastian Huber <sebastian.huber@…>, on Apr 5, 2019 at 6:03:12 AM

rtems: Add rtems_scheduler_get_processor()

Add rtems_scheduler_get_processor() as a replacement for
rtems_get_current_processor(). The rtems_get_current_processor() is a
bit orphaned. Adopt it by the Scheduler Manager. This is in line with
the glibc sched_getcpu() function.

Deprecate rtems_get_current_processor().

Update #3731.

  • Property mode set to 100644
File size: 4.7 KB
Line 
1/*
2 * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#ifdef HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include "tmacros.h"
20
21#include <rtems.h>
22#include <rtems/libcsupport.h>
23#include <rtems/score/percpu.h>
24#include <rtems/score/smpbarrier.h>
25
26#include <test_support.h>
27
28#define CPU_COUNT 2
29
30#define SCHEDULER_A rtems_build_name(' ', ' ', ' ', 'A')
31
32#define SCHEDULER_B rtems_build_name(' ', ' ', ' ', 'B')
33
34const char rtems_test_name[] = "SMPCLOCK 1";
35
36typedef struct {
37  SMP_barrier_Control barrier;
38  SMP_barrier_State delay_barrier_state;
39  SMP_barrier_State timer_barrier_state;
40} test_context;
41
42static test_context test_instance = {
43  .barrier = SMP_BARRIER_CONTROL_INITIALIZER,
44  .delay_barrier_state = SMP_BARRIER_STATE_INITIALIZER,
45  .timer_barrier_state = SMP_BARRIER_STATE_INITIALIZER
46};
47
48static void wait(test_context *ctx, SMP_barrier_State *bs)
49{
50  _SMP_barrier_Wait(&ctx->barrier, bs, CPU_COUNT);
51}
52
53static void timer_isr(rtems_id id, void *arg)
54{
55  test_context *ctx = arg;
56
57  /* (B) */
58  wait(ctx, &ctx->timer_barrier_state);
59}
60
61static void timer_task(rtems_task_argument arg)
62{
63  test_context *ctx = (test_context *) arg;
64  rtems_status_code sc;
65  rtems_id timer_id;
66
67  rtems_test_assert(rtems_scheduler_get_processor() == 1);
68
69  sc = rtems_timer_create(SCHEDULER_B, &timer_id);
70  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
71
72  /* (A) */
73  wait(ctx, &ctx->timer_barrier_state);
74
75  sc = rtems_timer_fire_after(timer_id, 1, timer_isr, ctx);
76  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
77
78  sc = rtems_task_wake_after(1);
79  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
80
81  sc = rtems_timer_delete(timer_id);
82  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
83
84  /* (C) */
85  wait(ctx, &ctx->timer_barrier_state);
86
87  while (true) {
88    /* Wait for deletion */
89  }
90}
91
92static void delay_clock_tick(test_context *ctx)
93{
94  rtems_interrupt_level level;
95  const Per_CPU_Control *cpu_self = _Per_CPU_Get_by_index(0);
96  const Per_CPU_Control *cpu_other = _Per_CPU_Get_by_index(1);
97  uint64_t ticks;
98
99  rtems_test_assert(rtems_scheduler_get_processor() == 0);
100
101  rtems_test_spin_until_next_tick();
102  ticks = cpu_self->Watchdog.ticks;
103
104  rtems_interrupt_local_disable(level);
105
106  /* (A) */
107  wait(ctx, &ctx->delay_barrier_state);
108
109  /* (B) */
110  wait(ctx, &ctx->delay_barrier_state);
111
112  rtems_test_assert(cpu_self->Watchdog.ticks == ticks);
113  rtems_test_assert(cpu_other->Watchdog.ticks == ticks + 1);
114
115  rtems_interrupt_local_enable(level);
116
117  rtems_test_assert(cpu_self->Watchdog.ticks == ticks + 1);
118  rtems_test_assert(cpu_other->Watchdog.ticks == ticks + 1);
119
120  /* (C) */
121  wait(ctx, &ctx->delay_barrier_state);
122}
123
124static void test(void)
125{
126  test_context *ctx = &test_instance;
127  rtems_status_code sc;
128  rtems_id scheduler_b_id;
129  rtems_id task_id;
130
131  sc = rtems_scheduler_ident(SCHEDULER_B, &scheduler_b_id);
132  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
133
134  sc = rtems_task_create(
135    SCHEDULER_B,
136    255,
137    RTEMS_MINIMUM_STACK_SIZE,
138    RTEMS_DEFAULT_MODES,
139    RTEMS_DEFAULT_ATTRIBUTES,
140    &task_id
141  );
142  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
143
144  sc = rtems_task_set_scheduler(task_id, scheduler_b_id, 1);
145  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
146
147  sc = rtems_task_start(task_id, timer_task, (rtems_task_argument) ctx);
148  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
149
150  delay_clock_tick(ctx);
151
152  sc = rtems_task_delete(task_id);
153  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
154}
155
156static void Init(rtems_task_argument arg)
157{
158  rtems_resource_snapshot snapshot;
159
160  TEST_BEGIN();
161
162  rtems_resource_snapshot_take(&snapshot);
163
164  if (rtems_get_processor_count() == CPU_COUNT) {
165    test();
166  }
167
168  rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
169
170  TEST_END();
171  rtems_test_exit(0);
172}
173
174#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
175#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
176
177#define CONFIGURE_MAXIMUM_PROCESSORS CPU_COUNT
178
179#define CONFIGURE_SCHEDULER_SIMPLE_SMP
180
181#include <rtems/scheduler.h>
182
183RTEMS_SCHEDULER_SIMPLE_SMP(a);
184RTEMS_SCHEDULER_SIMPLE_SMP(b);
185
186#define CONFIGURE_SCHEDULER_TABLE_ENTRIES \
187  RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(a, SCHEDULER_A), \
188  RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(b, SCHEDULER_B)
189
190#define CONFIGURE_SCHEDULER_ASSIGNMENTS \
191  RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
192  RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL)
193
194#define CONFIGURE_MAXIMUM_TASKS CPU_COUNT
195
196#define CONFIGURE_MAXIMUM_TIMERS 1
197
198#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
199
200#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
201
202#define CONFIGURE_INIT
203
204#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.