summaryrefslogtreecommitdiffstats
path: root/testsuites/smptests/smpmulticast01/init.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2019-04-11 15:39:36 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2019-04-12 09:44:48 +0200
commitf410b31be4687746003d53568ee30854b848468e (patch)
tree35c0c50129d535bb5d46013bd3f162e402602a8c /testsuites/smptests/smpmulticast01/init.c
parentscore: Rework SMP multicast action (diff)
downloadrtems-f410b31be4687746003d53568ee30854b848468e.tar.bz2
score: Improve _SMP_Multicast_action()
Let it work during system initialization.
Diffstat (limited to 'testsuites/smptests/smpmulticast01/init.c')
-rw-r--r--testsuites/smptests/smpmulticast01/init.c140
1 files changed, 94 insertions, 46 deletions
diff --git a/testsuites/smptests/smpmulticast01/init.c b/testsuites/smptests/smpmulticast01/init.c
index e599a78bde..3f3f7dc3fc 100644
--- a/testsuites/smptests/smpmulticast01/init.c
+++ b/testsuites/smptests/smpmulticast01/init.c
@@ -104,18 +104,15 @@ static void action(void *arg)
static void test_unicast(
test_context *ctx,
- void (*multicast_action)(const Processor_mask *, SMP_Action_handler, void *),
- bool before_multitasking
+ void (*multicast_action)(const Processor_mask *, SMP_Action_handler, void *)
)
{
uint32_t step;
uint32_t i;
uint32_t n;
- uint32_t self;
T_plan(1);
step = 0;
- self = rtems_scheduler_get_processor();
n = rtems_scheduler_get_processor_maximum();
for (i = 0; i < n; ++i) {
@@ -134,18 +131,10 @@ static void test_unicast(
++step;
id = _Atomic_Load_uint(&ctx->id[j], ATOMIC_ORDER_RELAXED);
- if (before_multitasking) {
- if (j == self) {
- T_quiet_eq_uint(j + 1, id);
- } else {
- T_quiet_eq_uint(0, id);
- }
+ if (j == i) {
+ T_quiet_eq_uint(j + 1, id);
} else {
- if (j == i) {
- T_quiet_eq_uint(j + 1, id);
- } else {
- T_quiet_eq_uint(0, id);
- }
+ T_quiet_eq_uint(0, id);
}
}
}
@@ -155,18 +144,15 @@ static void test_unicast(
static void test_broadcast(
test_context *ctx,
- void (*multicast_action)(const Processor_mask *, SMP_Action_handler, void *),
- bool before_multitasking
+ void (*multicast_action)(const Processor_mask *, SMP_Action_handler, void *)
)
{
uint32_t step;
uint32_t i;
uint32_t n;
- uint32_t self;
T_plan(1);
step = 0;
- self = rtems_scheduler_get_processor();
n = rtems_scheduler_get_processor_maximum();
for (i = 0; i < n; ++i) {
@@ -181,16 +167,7 @@ static void test_broadcast(
++step;
id = _Atomic_Load_uint(&ctx->id[j], ATOMIC_ORDER_RELAXED);
-
- if (before_multitasking) {
- if (j == self) {
- T_quiet_eq_uint(j + 1, id);
- } else {
- T_quiet_eq_uint(0, id);
- }
- } else {
- T_quiet_eq_uint(j + 1, id);
- }
+ T_quiet_eq_uint(j + 1, id);
}
}
@@ -204,27 +181,27 @@ static void test_before_multitasking(void)
ctx = &test_instance;
T_case_begin("UnicastBeforeMultitasking", NULL);
- test_unicast(ctx, _SMP_Multicast_action, true);
+ test_unicast(ctx, _SMP_Multicast_action);
T_case_end();
T_case_begin("UnicastBeforeMultitaskingIRQDisabled", NULL);
- test_unicast(ctx, multicast_action_irq_disabled, true);
+ test_unicast(ctx, multicast_action_irq_disabled);
T_case_end();
T_case_begin("UnicastBeforeMultitaskingDispatchDisabled", NULL);
- test_unicast(ctx, multicast_action_dispatch_disabled, true);
+ test_unicast(ctx, multicast_action_dispatch_disabled);
T_case_end();
T_case_begin("BroadcastBeforeMultitasking", NULL);
- test_broadcast(ctx, _SMP_Multicast_action, true);
+ test_broadcast(ctx, _SMP_Multicast_action);
T_case_end();
T_case_begin("BroadcastBeforeMultitaskingIRQDisabled", NULL);
- test_broadcast(ctx, multicast_action_irq_disabled, true);
+ test_broadcast(ctx, multicast_action_irq_disabled);
T_case_end();
T_case_begin("BroadcastBeforeMultitaskingDispatchDisabled", NULL);
- test_broadcast(ctx, multicast_action_dispatch_disabled, true);
+ test_broadcast(ctx, multicast_action_dispatch_disabled);
T_case_end();
}
@@ -241,41 +218,108 @@ RTEMS_SYSINIT_ITEM(
RTEMS_SYSINIT_ORDER_LAST
);
+static void set_wrong_cpu_state(void *arg)
+{
+ Per_CPU_Control *cpu_self;
+
+ cpu_self = arg;
+ T_step_eq_ptr(0, cpu_self, _Per_CPU_Get());
+ cpu_self->state = 123;
+
+ while (true) {
+ /* Do nothing */
+ }
+}
+
+static void test_wrong_cpu_state_to_perform_jobs(void)
+{
+ Per_CPU_Control *cpu_self;
+ rtems_interrupt_level level;
+ Processor_mask targets;
+ uint32_t cpu_index;
+
+ T_case_begin("WrongCPUStateToPerformJobs", NULL);
+ T_plan(4);
+ cpu_self = _Thread_Dispatch_disable();
+
+ cpu_index = _Per_CPU_Get_index(cpu_self);
+ cpu_index = (cpu_index + 1) % rtems_scheduler_get_processor_maximum();
+ _Processor_mask_Zero(&targets);
+ _Processor_mask_Set(&targets, cpu_index);
+
+ rtems_interrupt_local_disable(level);
+
+ _SMP_Multicast_action(
+ &targets,
+ set_wrong_cpu_state,
+ _Per_CPU_Get_by_index(cpu_index)
+ );
+
+ /* If everything is all right, we don't end up here */
+ rtems_interrupt_local_enable(level);
+ _Thread_Dispatch_enable(cpu_self);
+ rtems_fatal(RTEMS_FATAL_SOURCE_APPLICATION, 0);
+}
+
static void Init(rtems_task_argument arg)
{
test_context *ctx;
- bool ok;
ctx = &test_instance;
T_case_begin("UnicastDuringMultitasking", NULL);
- test_unicast(ctx, _SMP_Multicast_action, false);
+ test_unicast(ctx, _SMP_Multicast_action);
T_case_end();
T_case_begin("UnicastDuringMultitaskingIRQDisabled", NULL);
- test_unicast(ctx, multicast_action_irq_disabled, false);
+ test_unicast(ctx, multicast_action_irq_disabled);
T_case_end();
T_case_begin("UnicastDuringMultitaskingDispatchDisabled", NULL);
- test_unicast(ctx, multicast_action_dispatch_disabled, false);
+ test_unicast(ctx, multicast_action_dispatch_disabled);
T_case_end();
T_case_begin("BroadcastDuringMultitasking", NULL);
- test_broadcast(ctx, _SMP_Multicast_action, false);
+ test_broadcast(ctx, _SMP_Multicast_action);
T_case_end();
T_case_begin("BroadcastDuringMultitaskingIRQDisabled", NULL);
- test_broadcast(ctx, multicast_action_irq_disabled, false);
+ test_broadcast(ctx, multicast_action_irq_disabled);
T_case_end();
T_case_begin("BroadcastDuringMultitaskingDispatchDisabled", NULL);
- test_broadcast(ctx, multicast_action_dispatch_disabled, false);
+ test_broadcast(ctx, multicast_action_dispatch_disabled);
T_case_end();
- ok = T_run_finalize();
- rtems_test_assert(ok);
- TEST_END();
- rtems_test_exit(0);
+ if (rtems_scheduler_get_processor_maximum() > 1) {
+ test_wrong_cpu_state_to_perform_jobs();
+ } else {
+ rtems_fatal(RTEMS_FATAL_SOURCE_APPLICATION, 0);
+ }
+}
+
+static void fatal_extension(
+ rtems_fatal_source source,
+ bool always_set_to_false,
+ rtems_fatal_code code
+)
+{
+ bool ok;
+
+ if (source == RTEMS_FATAL_SOURCE_SMP) {
+ T_step_eq_int(1, source, RTEMS_FATAL_SOURCE_SMP);
+ T_step_false(2, always_set_to_false, "unexpected argument value");
+ T_step_eq_int(3, code, SMP_FATAL_WRONG_CPU_STATE_TO_PERFORM_JOBS);
+ T_case_end();
+
+ ok = T_run_finalize();
+ rtems_test_assert(ok);
+ TEST_END();
+ } else if (source == RTEMS_FATAL_SOURCE_APPLICATION) {
+ ok = T_run_finalize();
+ rtems_test_assert(ok);
+ TEST_END();
+ }
}
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
@@ -284,6 +328,10 @@ static void Init(rtems_task_argument arg)
#define CONFIGURE_MAXIMUM_PROCESSORS CPU_COUNT
+#define CONFIGURE_INITIAL_EXTENSIONS \
+ { .fatal = fatal_extension }, \
+ RTEMS_TEST_INITIAL_EXTENSION
+
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
#define CONFIGURE_INIT