source: rtems/testsuites/smptests/smpmulticast01/init.c @ df8d7bd7

5
Last change on this file since df8d7bd7 was df8d7bd7, checked in by Sebastian Huber <sebastian.huber@…>, on 04/09/19 at 08:58:35

score: Use processor mask in _SMP_Multicast_action

Processor_mask is the internal data type to deal with processor sets.

  • Property mode set to 100644
File size: 7.0 KB
Line 
1/*
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (C) 2019 embedded brains GmbH
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <rtems/score/smpimpl.h>
29#include <rtems/score/atomic.h>
30#include <rtems/score/threaddispatch.h>
31#include <rtems/sysinit.h>
32#include <rtems.h>
33
34#include <string.h>
35
36#include <t.h>
37#include <tmacros.h>
38
39#define CPU_COUNT 32
40
41const char rtems_test_name[] = "SMPMULTICAST 1";
42
43static const T_config config = {
44  .name = "SMPMultiCast",
45  .putchar = T_putchar_default,
46  .verbosity = T_VERBOSE,
47  .now = T_now
48};
49
50typedef struct {
51  Atomic_Uint id[CPU_COUNT];
52} test_context;
53
54static test_context test_instance;
55
56static void multicast_action_irq_disabled(
57  const Processor_mask *targets,
58  SMP_Action_handler handler,
59  void *arg
60)
61{
62  rtems_interrupt_level level;
63
64  rtems_interrupt_local_disable(level);
65  _SMP_Multicast_action(targets, handler, arg);
66  rtems_interrupt_local_enable(level);
67}
68
69static void multicast_action_dispatch_disabled(
70  const Processor_mask *targets,
71  SMP_Action_handler handler,
72  void *arg
73)
74{
75  Per_CPU_Control *cpu_self;
76
77  cpu_self = _Thread_Dispatch_disable();
78  _SMP_Multicast_action(targets, handler, arg);
79  _Thread_Dispatch_enable(cpu_self);
80}
81
82static void action(void *arg)
83{
84  test_context *ctx;
85  uint32_t self;
86  unsigned expected;
87  bool success;
88
89  ctx = arg;
90  self = rtems_scheduler_get_processor();
91  expected = 0;
92  success = _Atomic_Compare_exchange_uint(
93    &ctx->id[self],
94    &expected,
95    self + 1,
96    ATOMIC_ORDER_RELAXED,
97    ATOMIC_ORDER_RELAXED
98  );
99  T_quiet_true(success, "set CPU identifier failed");
100}
101
102static void test_unicast(
103  test_context *ctx,
104  void (*multicast_action)(const Processor_mask *, SMP_Action_handler, void *),
105  bool before_multitasking
106)
107{
108  uint32_t step;
109  uint32_t i;
110  uint32_t n;
111  uint32_t self;
112
113  T_plan(1);
114  step = 0;
115  self = rtems_scheduler_get_processor();
116  n = rtems_scheduler_get_processor_maximum();
117
118  for (i = 0; i < n; ++i) {
119    Processor_mask cpus;
120    uint32_t j;
121
122    memset(ctx, 0, sizeof(*ctx));
123
124    _Processor_mask_Zero(&cpus);
125    _Processor_mask_Set(&cpus, i);
126    (*multicast_action)(&cpus, action, ctx);
127
128    for (j = 0; j < n; ++j) {
129      unsigned id;
130
131      ++step;
132      id = _Atomic_Load_uint(&ctx->id[j], ATOMIC_ORDER_RELAXED);
133
134      if (before_multitasking) {
135        if (j == self) {
136          T_quiet_eq_uint(j + 1, id);
137        } else {
138          T_quiet_eq_uint(0, id);
139        }
140      } else {
141        if (j == i) {
142          T_quiet_eq_uint(j + 1, id);
143        } else {
144          T_quiet_eq_uint(0, id);
145        }
146      }
147    }
148  }
149
150  T_step_eq_u32(0, step, n * n);
151}
152
153static void test_broadcast(
154  test_context *ctx,
155  void (*multicast_action)(const Processor_mask *, SMP_Action_handler, void *),
156  bool before_multitasking
157)
158{
159  uint32_t step;
160  uint32_t i;
161  uint32_t n;
162  uint32_t self;
163
164  T_plan(1);
165  step = 0;
166  self = rtems_scheduler_get_processor();
167  n = rtems_scheduler_get_processor_maximum();
168
169  for (i = 0; i < n; ++i) {
170    uint32_t j;
171
172    memset(ctx, 0, sizeof(*ctx));
173
174    (*multicast_action)(NULL, action, ctx);
175
176    for (j = 0; j < n; ++j) {
177      unsigned id;
178
179      ++step;
180      id = _Atomic_Load_uint(&ctx->id[j], ATOMIC_ORDER_RELAXED);
181
182      if (before_multitasking) {
183        if (j == self) {
184          T_quiet_eq_uint(j + 1, id);
185        } else {
186          T_quiet_eq_uint(0, id);
187        }
188      } else {
189        T_quiet_eq_uint(j + 1, id);
190      }
191    }
192  }
193
194  T_step_eq_u32(0, step, n * n);
195}
196
197static void test_before_multitasking(void)
198{
199  test_context *ctx;
200
201  ctx = &test_instance;
202
203  T_case_begin("UnicastBeforeMultitasking", NULL);
204  test_unicast(ctx, _SMP_Multicast_action, true);
205  T_case_end();
206
207  T_case_begin("UnicastBeforeMultitaskingIRQDisabled", NULL);
208  test_unicast(ctx, multicast_action_irq_disabled, true);
209  T_case_end();
210
211  T_case_begin("UnicastBeforeMultitaskingDispatchDisabled", NULL);
212  test_unicast(ctx, multicast_action_dispatch_disabled, true);
213  T_case_end();
214
215  T_case_begin("BroadcastBeforeMultitasking", NULL);
216  test_broadcast(ctx, _SMP_Multicast_action, true);
217  T_case_end();
218
219  T_case_begin("BroadcastBeforeMultitaskingIRQDisabled", NULL);
220  test_broadcast(ctx, multicast_action_irq_disabled, true);
221  T_case_end();
222
223  T_case_begin("BroadcastBeforeMultitaskingDispatchDisabled", NULL);
224  test_broadcast(ctx, multicast_action_dispatch_disabled, true);
225  T_case_end();
226}
227
228static void after_drivers(void)
229{
230  TEST_BEGIN();
231  T_run_initialize(&config);
232  test_before_multitasking();
233}
234
235RTEMS_SYSINIT_ITEM(
236  after_drivers,
237  RTEMS_SYSINIT_DEVICE_DRIVERS,
238  RTEMS_SYSINIT_ORDER_LAST
239);
240
241static void Init(rtems_task_argument arg)
242{
243  test_context *ctx;
244  bool ok;
245
246  ctx = &test_instance;
247
248  T_case_begin("UnicastDuringMultitasking", NULL);
249  test_unicast(ctx, _SMP_Multicast_action, false);
250  T_case_end();
251
252  T_case_begin("UnicastDuringMultitaskingIRQDisabled", NULL);
253  test_unicast(ctx, multicast_action_irq_disabled, false);
254  T_case_end();
255
256  T_case_begin("UnicastDuringMultitaskingDispatchDisabled", NULL);
257  test_unicast(ctx, multicast_action_dispatch_disabled, false);
258  T_case_end();
259
260  T_case_begin("BroadcastDuringMultitasking", NULL);
261  test_broadcast(ctx, _SMP_Multicast_action, false);
262  T_case_end();
263
264  T_case_begin("BroadcastDuringMultitaskingIRQDisabled", NULL);
265  test_broadcast(ctx, multicast_action_irq_disabled, false);
266  T_case_end();
267
268  T_case_begin("BroadcastDuringMultitaskingDispatchDisabled", NULL);
269  test_broadcast(ctx, multicast_action_dispatch_disabled, false);
270  T_case_end();
271
272  ok = T_run_finalize();
273  rtems_test_assert(ok);
274  TEST_END();
275  rtems_test_exit(0);
276}
277
278#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
279
280#define CONFIGURE_MAXIMUM_TASKS 1
281
282#define CONFIGURE_MAXIMUM_PROCESSORS CPU_COUNT
283
284#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
285
286#define CONFIGURE_INIT
287
288#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.