[PATCH v1 3/3] smpthreadpin02: Adapt test from smpthreadpin01
Ryan Long
ryan.long at oarcorp.com
Wed Nov 17 15:33:53 UTC 2021
Split code at the end of the smpthreadpin01 test so that it could be reused
for the smpthreadpin02 test.
---
spec/build/testsuites/smptests/grp.yml | 2 +
spec/build/testsuites/smptests/smpthreadpin01.yml | 2 +-
spec/build/testsuites/smptests/smpthreadpin02.yml | 20 +
testsuites/smptests/include/smpthreadpin.h | 593 +++++++++++++++++++++
testsuites/smptests/smpthreadpin01/init.c | 581 +-------------------
testsuites/smptests/smpthreadpin02/init.c | 56 ++
.../smptests/smpthreadpin02/smpthreadpin02.doc | 12 +
.../smptests/smpthreadpin02/smpthreadpin02.scn | 35 ++
8 files changed, 721 insertions(+), 580 deletions(-)
create mode 100644 spec/build/testsuites/smptests/smpthreadpin02.yml
create mode 100644 testsuites/smptests/include/smpthreadpin.h
create mode 100644 testsuites/smptests/smpthreadpin02/init.c
create mode 100644 testsuites/smptests/smpthreadpin02/smpthreadpin02.doc
create mode 100644 testsuites/smptests/smpthreadpin02/smpthreadpin02.scn
diff --git a/spec/build/testsuites/smptests/grp.yml b/spec/build/testsuites/smptests/grp.yml
index d6a1bf5..7b8cb62 100644
--- a/spec/build/testsuites/smptests/grp.yml
+++ b/spec/build/testsuites/smptests/grp.yml
@@ -133,6 +133,8 @@ links:
- role: build-dependency
uid: smpthreadpin01
- role: build-dependency
+ uid: smpthreadpin02
+- role: build-dependency
uid: smpunsupported01
- role: build-dependency
uid: smpwakeafter01
diff --git a/spec/build/testsuites/smptests/smpthreadpin01.yml b/spec/build/testsuites/smptests/smpthreadpin01.yml
index 9de0166..21f549d 100644
--- a/spec/build/testsuites/smptests/smpthreadpin01.yml
+++ b/spec/build/testsuites/smptests/smpthreadpin01.yml
@@ -8,7 +8,7 @@ cxxflags: []
enabled-by:
- RTEMS_SMP
features: c cprogram
-includes: []
+includes: [testsuites/smptests/include]
ldflags: []
links: []
source:
diff --git a/spec/build/testsuites/smptests/smpthreadpin02.yml b/spec/build/testsuites/smptests/smpthreadpin02.yml
new file mode 100644
index 0000000..0f07ca4
--- /dev/null
+++ b/spec/build/testsuites/smptests/smpthreadpin02.yml
@@ -0,0 +1,20 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2021 On-Line Applications Research Corporation (OAR).
+cppflags: []
+cxxflags: []
+enabled-by:
+- RTEMS_SMP
+features: c cprogram
+includes: [testsuites/smptests/include]
+ldflags: []
+links: []
+source:
+- testsuites/smptests/smpthreadpin02/init.c
+stlib: []
+target: testsuites/smptests/smpthreadpin02.exe
+type: build
+use-after: []
+use-before: []
diff --git a/testsuites/smptests/include/smpthreadpin.h b/testsuites/smptests/include/smpthreadpin.h
new file mode 100644
index 0000000..75d24d8
--- /dev/null
+++ b/testsuites/smptests/include/smpthreadpin.h
@@ -0,0 +1,593 @@
+/*
+ * Copyright (c) 2018 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/thread.h>
+#include <rtems/score/threadimpl.h>
+
+#include <tmacros.h>
+
+#define CPU_COUNT 2
+
+#define SCHED_A rtems_build_name(' ', ' ', ' ', 'A')
+
+#define SCHED_B rtems_build_name(' ', ' ', ' ', 'B')
+
+#define EVENT_WAKEUP_MASTER RTEMS_EVENT_0
+
+#define EVENT_MTX_LOCK RTEMS_EVENT_1
+
+#define EVENT_MTX_UNLOCK RTEMS_EVENT_2
+
+#define EVENT_MOVE_BUSY_TO_CPU_0 RTEMS_EVENT_3
+
+#define EVENT_MOVE_BUSY_TO_CPU_1 RTEMS_EVENT_4
+
+#define EVENT_MOVE_SELF_TO_CPU_0 RTEMS_EVENT_5
+
+#define EVENT_MOVE_SELF_TO_CPU_1 RTEMS_EVENT_6
+
+#define EVENT_SET_SELF_PRIO_TO_LOW RTEMS_EVENT_7
+
+#define EVENT_SET_BUSY_PRIO_TO_IDLE RTEMS_EVENT_8
+
+#define EVENT_SET_FLAG RTEMS_EVENT_9
+
+#define PRIO_IDLE 6
+
+#define PRIO_VERY_LOW 5
+
+#define PRIO_LOW 4
+
+#define PRIO_MIDDLE 3
+
+#define PRIO_HIGH 2
+
+#define PRIO_VERY_HIGH 1
+
+typedef struct {
+ rtems_id master;
+ rtems_id event;
+ rtems_id event_2;
+ rtems_id busy;
+ rtems_id sched_a;
+ rtems_id sched_b;
+ rtems_mutex mtx;
+ volatile bool flag;
+} test_context;
+
+static test_context test_instance;
+
+static rtems_task_priority set_prio(rtems_id id, rtems_task_priority prio)
+{
+ rtems_status_code sc;
+ rtems_task_priority old_prio;
+
+ old_prio = 0xffffffff;
+ sc = rtems_task_set_priority(id, prio, &old_prio);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ return old_prio;
+}
+
+static void set_affinity(rtems_id task, uint32_t cpu_index)
+{
+ rtems_status_code sc;
+ rtems_id sched_cpu;
+ rtems_id sched_task;
+ cpu_set_t set;
+
+ sc = rtems_scheduler_ident_by_processor(cpu_index, &sched_cpu);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_get_scheduler(task, &sched_task);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ if (sched_task != sched_cpu) {
+ rtems_task_priority prio;
+
+ CPU_FILL(&set);
+ sc = rtems_task_set_affinity(task, sizeof(set), &set);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ prio = set_prio(task, RTEMS_CURRENT_PRIORITY);
+ sc = rtems_task_set_scheduler(task, sched_cpu, prio);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+ }
+
+ CPU_ZERO(&set);
+ CPU_SET((int) cpu_index, &set);
+ sc = rtems_task_set_affinity(task, sizeof(set), &set);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void send_events(rtems_id task, rtems_event_set events)
+{
+ rtems_status_code sc;
+
+ sc = rtems_event_send(task, events);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static rtems_event_set wait_for_events(void)
+{
+ rtems_event_set events;
+ rtems_status_code sc;
+
+ sc = rtems_event_receive(
+ RTEMS_ALL_EVENTS,
+ RTEMS_EVENT_ANY | RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT,
+ &events
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ return events;
+}
+
+static void pin(bool blocked)
+{
+ Per_CPU_Control *cpu_self;
+ Thread_Control *executing;
+
+ cpu_self = _Thread_Dispatch_disable();
+ executing = _Per_CPU_Get_executing(cpu_self);
+
+ if (blocked) {
+ _Thread_Set_state(executing, STATES_SUSPENDED);
+ }
+
+ _Thread_Pin(executing);
+
+ if (blocked) {
+ _Thread_Clear_state(executing, STATES_SUSPENDED);
+ }
+
+ _Thread_Dispatch_enable(cpu_self);
+}
+
+static void unpin(bool blocked)
+{
+ Per_CPU_Control *cpu_self;
+ Thread_Control *executing;
+
+ cpu_self = _Thread_Dispatch_disable();
+ executing = _Per_CPU_Get_executing(cpu_self);
+
+ if (blocked) {
+ _Thread_Set_state(executing, STATES_SUSPENDED);
+ }
+
+ _Thread_Unpin(executing, cpu_self);
+
+ if (blocked) {
+ _Thread_Clear_state(executing, STATES_SUSPENDED);
+ }
+
+ _Thread_Dispatch_enable(cpu_self);
+}
+
+static void event_task(rtems_task_argument arg)
+{
+ test_context *ctx;
+
+ ctx = (test_context *) arg;
+
+ while (true) {
+ rtems_event_set events;
+
+ events = wait_for_events();
+
+ /*
+ * The order of event processing is important!
+ */
+
+ if ((events & EVENT_MTX_LOCK) != 0) {
+ rtems_mutex_lock(&ctx->mtx);
+ }
+
+ if ((events & EVENT_MTX_UNLOCK) != 0) {
+ rtems_mutex_unlock(&ctx->mtx);
+ }
+
+ if ((events & EVENT_MOVE_BUSY_TO_CPU_0) != 0) {
+ set_affinity(ctx->busy, 0);
+ }
+
+ if ((events & EVENT_MOVE_BUSY_TO_CPU_1) != 0) {
+ set_affinity(ctx->busy, 1);
+ }
+
+ if ((events & EVENT_MOVE_SELF_TO_CPU_0) != 0) {
+ set_affinity(RTEMS_SELF, 0);
+ }
+
+ if ((events & EVENT_MOVE_SELF_TO_CPU_1) != 0) {
+ set_affinity(RTEMS_SELF, 1);
+ }
+
+ if ((events & EVENT_SET_SELF_PRIO_TO_LOW) != 0) {
+ set_prio(RTEMS_SELF, PRIO_LOW);
+ }
+
+ if ((events & EVENT_SET_BUSY_PRIO_TO_IDLE) != 0) {
+ set_prio(ctx->busy, PRIO_IDLE);
+ }
+
+ if ((events & EVENT_SET_FLAG) != 0) {
+ ctx->flag = true;
+ }
+
+ if ((events & EVENT_WAKEUP_MASTER) != 0) {
+ send_events(ctx->master, EVENT_WAKEUP_MASTER);
+ }
+ }
+}
+
+static void busy_task(rtems_task_argument arg)
+{
+ (void) arg;
+
+ _CPU_Thread_Idle_body(0);
+}
+
+static const char *blocked_or_ready(bool blocked)
+{
+ return blocked ? "blocked" : "ready";
+}
+
+static void reconfigure_scheduler(test_context *ctx)
+{
+ rtems_status_code sc;
+
+ puts("reconfigure scheduler");
+
+ set_prio(ctx->master, PRIO_MIDDLE);
+ set_prio(ctx->event, PRIO_LOW);
+ set_prio(ctx->event_2, PRIO_VERY_LOW);
+ set_prio(ctx->busy, PRIO_IDLE);
+
+ set_affinity(ctx->master, 0);
+ set_affinity(ctx->event, 0);
+ set_affinity(ctx->event_2, 0);
+ set_affinity(ctx->busy, 0);
+
+ sc = rtems_scheduler_remove_processor(ctx->sched_a, 1);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_scheduler_add_processor(ctx->sched_b, 1);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void test_simple_pin_unpin(test_context *ctx, int run)
+{
+ Per_CPU_Control *cpu_self;
+ Thread_Control *executing;
+
+ printf("test simple wait unpin (run %i)\n", run);
+
+ set_affinity(ctx->busy, 0);
+ set_prio(ctx->busy, PRIO_IDLE);
+ set_prio(RTEMS_SELF, PRIO_MIDDLE);
+ rtems_test_assert(rtems_scheduler_get_processor() == 1);
+
+ cpu_self = _Thread_Dispatch_disable();
+ executing = _Per_CPU_Get_executing(cpu_self);
+ _Thread_Pin(executing);
+
+ rtems_test_assert(rtems_scheduler_get_processor() == 1);
+
+ _Thread_Unpin(executing, cpu_self);
+ _Thread_Dispatch_enable(cpu_self);
+
+ rtems_test_assert(rtems_scheduler_get_processor() == 1);
+}
+
+static void test_pin_wait_unpin(test_context *ctx, bool blocked, int run)
+{
+ printf("test pin wait unpin (%s, run %i)\n", blocked_or_ready(blocked), run);
+
+ set_affinity(ctx->busy, 0);
+ set_prio(ctx->busy, PRIO_IDLE);
+ set_prio(RTEMS_SELF, PRIO_MIDDLE);
+ set_prio(ctx->event, PRIO_LOW);
+ set_affinity(ctx->event, 1);
+ rtems_test_assert(rtems_scheduler_get_processor() == 1);
+
+ pin(blocked);
+ rtems_test_assert(rtems_scheduler_get_processor() == 1);
+
+ send_events(ctx->event, EVENT_WAKEUP_MASTER);
+ rtems_test_assert(rtems_scheduler_get_processor() == 1);
+ wait_for_events();
+ rtems_test_assert(rtems_scheduler_get_processor() == 1);
+
+ set_prio(ctx->busy, PRIO_HIGH);
+ set_affinity(ctx->busy, 0);
+ unpin(blocked);
+ rtems_test_assert(rtems_scheduler_get_processor() == 1);
+}
+
+static void test_pin_preempt_unpin(test_context *ctx, bool blocked, int run)
+{
+ printf(
+ "test pin preempt unpin (%s, run %i)\n",
+ blocked_or_ready(blocked),
+ run
+ );
+
+ set_prio(RTEMS_SELF, PRIO_MIDDLE);
+ set_prio(ctx->event, PRIO_VERY_HIGH);
+ set_prio(ctx->busy, PRIO_HIGH);
+ set_affinity(ctx->event, 0);
+ set_affinity(ctx->busy, 0);
+ rtems_test_assert(rtems_scheduler_get_processor() == 1);
+
+ pin(blocked);
+ rtems_test_assert(rtems_scheduler_get_processor() == 1);
+
+ ctx->flag = false;
+ send_events(
+ ctx->event,
+ EVENT_MOVE_BUSY_TO_CPU_1 | EVENT_SET_SELF_PRIO_TO_LOW
+ | EVENT_SET_BUSY_PRIO_TO_IDLE | EVENT_SET_FLAG
+ );
+
+ while (!ctx->flag) {
+ rtems_test_assert(rtems_scheduler_get_processor() == 1);
+ }
+
+ set_affinity(ctx->busy, 0);
+ unpin(blocked);
+ rtems_test_assert(rtems_scheduler_get_processor() == 1);
+}
+
+static void test_pin_home_no_help_unpin(
+ test_context *ctx,
+ bool blocked,
+ int run
+)
+{
+ rtems_status_code sc;
+
+ printf(
+ "test pin home no help unpin (%s, run %i)\n",
+ blocked_or_ready(blocked),
+ run
+ );
+
+ set_affinity(ctx->busy, 1);
+ set_prio(ctx->busy, PRIO_IDLE);
+ set_prio(RTEMS_SELF, PRIO_MIDDLE);
+ rtems_test_assert(rtems_scheduler_get_processor() == 0);
+
+ pin(blocked);
+ rtems_test_assert(rtems_scheduler_get_processor() == 0);
+
+ sc = rtems_task_set_scheduler(RTEMS_SELF, ctx->sched_b, 1);
+ rtems_test_assert(sc == RTEMS_RESOURCE_IN_USE);
+
+ rtems_mutex_lock(&ctx->mtx);
+ rtems_test_assert(rtems_scheduler_get_processor() == 0);
+
+ set_affinity(ctx->event, 1);
+ set_prio(ctx->event, PRIO_MIDDLE);
+
+ send_events(ctx->event, EVENT_MTX_LOCK);
+ set_prio(ctx->event_2, PRIO_LOW);
+ set_affinity(ctx->event_2, 1);
+ send_events(ctx->event_2, EVENT_WAKEUP_MASTER);
+ wait_for_events();
+
+ /* Now the event task can help us */
+ rtems_test_assert(ctx->mtx._Queue._heads != NULL);
+ rtems_test_assert(rtems_scheduler_get_processor() == 0);
+
+ set_affinity(ctx->event_2, 0);
+ set_affinity(ctx->busy, 1);
+ set_prio(ctx->busy, PRIO_HIGH);
+ send_events(
+ ctx->event_2,
+ EVENT_MOVE_BUSY_TO_CPU_0 | EVENT_MOVE_SELF_TO_CPU_1
+ | EVENT_SET_SELF_PRIO_TO_LOW | EVENT_SET_BUSY_PRIO_TO_IDLE
+ );
+ set_prio(ctx->event_2, PRIO_VERY_HIGH);
+ rtems_test_assert(rtems_scheduler_get_processor() == 0);
+
+ rtems_mutex_unlock(&ctx->mtx);
+ rtems_test_assert(rtems_scheduler_get_processor() == 0);
+
+ send_events(ctx->event, EVENT_WAKEUP_MASTER | EVENT_MTX_UNLOCK);
+ wait_for_events();
+ rtems_test_assert(rtems_scheduler_get_processor() == 0);
+
+ unpin(blocked);
+ rtems_test_assert(rtems_scheduler_get_processor() == 0);
+}
+
+static void test_pin_foreign_no_help_unpin(
+ test_context *ctx,
+ bool blocked,
+ int run
+)
+{
+ printf(
+ "test pin foreign no help unpin (%s, run %i)\n",
+ blocked_or_ready(blocked),
+ run
+ );
+
+ set_affinity(ctx->busy, 1);
+ set_prio(ctx->busy, PRIO_IDLE);
+ set_prio(RTEMS_SELF, PRIO_MIDDLE);
+ rtems_test_assert(rtems_scheduler_get_processor() == 0);
+
+ rtems_mutex_lock(&ctx->mtx);
+ rtems_test_assert(rtems_scheduler_get_processor() == 0);
+
+ set_affinity(ctx->event, 1);
+ set_prio(ctx->event, PRIO_MIDDLE);
+ send_events(ctx->event, EVENT_MTX_LOCK);
+ set_prio(ctx->event_2, PRIO_LOW);
+ set_affinity(ctx->event_2, 1);
+ send_events(ctx->event_2, EVENT_WAKEUP_MASTER);
+ wait_for_events();
+
+ /* Now the event task can help us */
+ rtems_test_assert(ctx->mtx._Queue._heads != NULL);
+ rtems_test_assert(rtems_scheduler_get_processor() == 0);
+
+ /* Request help */
+ set_affinity(ctx->busy, 0);
+ set_prio(ctx->busy, PRIO_HIGH);
+ rtems_test_assert(rtems_scheduler_get_processor() == 1);
+
+ /* Pin while using foreign scheduler */
+ pin(blocked);
+ rtems_test_assert(rtems_scheduler_get_processor() == 1);
+
+ set_affinity(ctx->event_2, 1);
+ send_events(
+ ctx->event_2,
+ EVENT_MOVE_BUSY_TO_CPU_1 | EVENT_MOVE_SELF_TO_CPU_0
+ | EVENT_SET_SELF_PRIO_TO_LOW | EVENT_SET_BUSY_PRIO_TO_IDLE
+ );
+ set_prio(ctx->event_2, PRIO_VERY_HIGH);
+ rtems_test_assert(rtems_scheduler_get_processor() == 1);
+
+ unpin(blocked);
+ rtems_test_assert(rtems_scheduler_get_processor() == 0);
+
+ set_prio(ctx->busy, PRIO_IDLE);
+ rtems_mutex_unlock(&ctx->mtx);
+ rtems_test_assert(rtems_scheduler_get_processor() == 0);
+
+ send_events(ctx->event, EVENT_WAKEUP_MASTER | EVENT_MTX_UNLOCK);
+ wait_for_events();
+ rtems_test_assert(rtems_scheduler_get_processor() == 0);
+}
+
+static void test(test_context *ctx)
+{
+ rtems_status_code sc;
+ int run;
+
+ ctx->master = rtems_task_self();
+
+ rtems_mutex_init(&ctx->mtx, "test");
+
+ sc = rtems_scheduler_ident(SCHED_A, &ctx->sched_a);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_scheduler_ident(SCHED_B, &ctx->sched_b);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_create(
+ rtems_build_name('B', 'U', 'S', 'Y'),
+ PRIO_HIGH,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &ctx->busy
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_start(ctx->busy, busy_task, (rtems_task_argument) ctx);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ set_affinity(ctx->busy, 0);
+ set_prio(ctx->busy, PRIO_IDLE);
+ rtems_test_assert(rtems_scheduler_get_processor() == 1);
+
+ sc = rtems_task_create(
+ rtems_build_name('E', 'V', 'T', '1'),
+ PRIO_LOW,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &ctx->event
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_start(ctx->event, event_task, (rtems_task_argument) ctx);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ send_events(ctx->event, EVENT_WAKEUP_MASTER);
+ wait_for_events();
+
+ sc = rtems_task_create(
+ rtems_build_name('E', 'V', 'T', '2'),
+ PRIO_LOW,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &ctx->event_2
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_start(ctx->event_2, event_task, (rtems_task_argument) ctx);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ send_events(ctx->event_2, EVENT_WAKEUP_MASTER);
+ wait_for_events();
+
+ for (run = 1; run <= 3; ++run) {
+ test_simple_pin_unpin(ctx, run);
+ test_pin_wait_unpin(ctx, true, run);
+ test_pin_wait_unpin(ctx, false, run);
+ test_pin_preempt_unpin(ctx, true, run);
+ test_pin_preempt_unpin(ctx, false, run);
+ }
+
+ reconfigure_scheduler(ctx);
+
+ for (run = 1; run <= 3; ++run) {
+ test_pin_home_no_help_unpin(ctx, true, run);
+ test_pin_home_no_help_unpin(ctx, false, run);
+ test_pin_foreign_no_help_unpin(ctx, true, run);
+ test_pin_foreign_no_help_unpin(ctx, false, run);
+ }
+}
+
+static void Init(rtems_task_argument arg)
+{
+ TEST_BEGIN();
+
+ if (rtems_scheduler_get_processor_maximum() == CPU_COUNT) {
+ test(&test_instance);
+ } else {
+ puts("warning: wrong processor count to run the test");
+ }
+
+ TEST_END();
+ rtems_test_exit(0);
+}
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
+
+#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
+
+#define CONFIGURE_MAXIMUM_PROCESSORS CPU_COUNT
+
+#define CONFIGURE_MAXIMUM_TASKS 4
+
+#define CONFIGURE_INIT_TASK_PRIORITY PRIO_MIDDLE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
diff --git a/testsuites/smptests/smpthreadpin01/init.c b/testsuites/smptests/smpthreadpin01/init.c
index 7c3c9b2..7684159 100644
--- a/testsuites/smptests/smpthreadpin01/init.c
+++ b/testsuites/smptests/smpthreadpin01/init.c
@@ -12,587 +12,10 @@
* http://www.rtems.org/license/LICENSE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <rtems.h>
-#include <rtems/thread.h>
-#include <rtems/score/threadimpl.h>
-
-#include <tmacros.h>
+#include <smpthreadpin.h>
const char rtems_test_name[] = "SMPTHREADPIN 1";
-#define CPU_COUNT 2
-
-#define SCHED_A rtems_build_name(' ', ' ', ' ', 'A')
-
-#define SCHED_B rtems_build_name(' ', ' ', ' ', 'B')
-
-#define EVENT_WAKEUP_MASTER RTEMS_EVENT_0
-
-#define EVENT_MTX_LOCK RTEMS_EVENT_1
-
-#define EVENT_MTX_UNLOCK RTEMS_EVENT_2
-
-#define EVENT_MOVE_BUSY_TO_CPU_0 RTEMS_EVENT_3
-
-#define EVENT_MOVE_BUSY_TO_CPU_1 RTEMS_EVENT_4
-
-#define EVENT_MOVE_SELF_TO_CPU_0 RTEMS_EVENT_5
-
-#define EVENT_MOVE_SELF_TO_CPU_1 RTEMS_EVENT_6
-
-#define EVENT_SET_SELF_PRIO_TO_LOW RTEMS_EVENT_7
-
-#define EVENT_SET_BUSY_PRIO_TO_IDLE RTEMS_EVENT_8
-
-#define EVENT_SET_FLAG RTEMS_EVENT_9
-
-#define PRIO_IDLE 6
-
-#define PRIO_VERY_LOW 5
-
-#define PRIO_LOW 4
-
-#define PRIO_MIDDLE 3
-
-#define PRIO_HIGH 2
-
-#define PRIO_VERY_HIGH 1
-
-typedef struct {
- rtems_id master;
- rtems_id event;
- rtems_id event_2;
- rtems_id busy;
- rtems_id sched_a;
- rtems_id sched_b;
- rtems_mutex mtx;
- volatile bool flag;
-} test_context;
-
-static test_context test_instance;
-
-static rtems_task_priority set_prio(rtems_id id, rtems_task_priority prio)
-{
- rtems_status_code sc;
- rtems_task_priority old_prio;
-
- old_prio = 0xffffffff;
- sc = rtems_task_set_priority(id, prio, &old_prio);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- return old_prio;
-}
-
-static void set_affinity(rtems_id task, uint32_t cpu_index)
-{
- rtems_status_code sc;
- rtems_id sched_cpu;
- rtems_id sched_task;
- cpu_set_t set;
-
- sc = rtems_scheduler_ident_by_processor(cpu_index, &sched_cpu);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- sc = rtems_task_get_scheduler(task, &sched_task);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- if (sched_task != sched_cpu) {
- rtems_task_priority prio;
-
- CPU_FILL(&set);
- sc = rtems_task_set_affinity(task, sizeof(set), &set);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- prio = set_prio(task, RTEMS_CURRENT_PRIORITY);
- sc = rtems_task_set_scheduler(task, sched_cpu, prio);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
- }
-
- CPU_ZERO(&set);
- CPU_SET((int) cpu_index, &set);
- sc = rtems_task_set_affinity(task, sizeof(set), &set);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-}
-
-static void send_events(rtems_id task, rtems_event_set events)
-{
- rtems_status_code sc;
-
- sc = rtems_event_send(task, events);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-}
-
-static rtems_event_set wait_for_events(void)
-{
- rtems_event_set events;
- rtems_status_code sc;
-
- sc = rtems_event_receive(
- RTEMS_ALL_EVENTS,
- RTEMS_EVENT_ANY | RTEMS_WAIT,
- RTEMS_NO_TIMEOUT,
- &events
- );
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- return events;
-}
-
-static void pin(bool blocked)
-{
- Per_CPU_Control *cpu_self;
- Thread_Control *executing;
-
- cpu_self = _Thread_Dispatch_disable();
- executing = _Per_CPU_Get_executing(cpu_self);
-
- if (blocked) {
- _Thread_Set_state(executing, STATES_SUSPENDED);
- }
-
- _Thread_Pin(executing);
-
- if (blocked) {
- _Thread_Clear_state(executing, STATES_SUSPENDED);
- }
-
- _Thread_Dispatch_enable(cpu_self);
-}
-
-static void unpin(bool blocked)
-{
- Per_CPU_Control *cpu_self;
- Thread_Control *executing;
-
- cpu_self = _Thread_Dispatch_disable();
- executing = _Per_CPU_Get_executing(cpu_self);
-
- if (blocked) {
- _Thread_Set_state(executing, STATES_SUSPENDED);
- }
-
- _Thread_Unpin(executing, cpu_self);
-
- if (blocked) {
- _Thread_Clear_state(executing, STATES_SUSPENDED);
- }
-
- _Thread_Dispatch_enable(cpu_self);
-}
-
-static void event_task(rtems_task_argument arg)
-{
- test_context *ctx;
-
- ctx = (test_context *) arg;
-
- while (true) {
- rtems_event_set events;
-
- events = wait_for_events();
-
- /*
- * The order of event processing is important!
- */
-
- if ((events & EVENT_MTX_LOCK) != 0) {
- rtems_mutex_lock(&ctx->mtx);
- }
-
- if ((events & EVENT_MTX_UNLOCK) != 0) {
- rtems_mutex_unlock(&ctx->mtx);
- }
-
- if ((events & EVENT_MOVE_BUSY_TO_CPU_0) != 0) {
- set_affinity(ctx->busy, 0);
- }
-
- if ((events & EVENT_MOVE_BUSY_TO_CPU_1) != 0) {
- set_affinity(ctx->busy, 1);
- }
-
- if ((events & EVENT_MOVE_SELF_TO_CPU_0) != 0) {
- set_affinity(RTEMS_SELF, 0);
- }
-
- if ((events & EVENT_MOVE_SELF_TO_CPU_1) != 0) {
- set_affinity(RTEMS_SELF, 1);
- }
-
- if ((events & EVENT_SET_SELF_PRIO_TO_LOW) != 0) {
- set_prio(RTEMS_SELF, PRIO_LOW);
- }
-
- if ((events & EVENT_SET_BUSY_PRIO_TO_IDLE) != 0) {
- set_prio(ctx->busy, PRIO_IDLE);
- }
-
- if ((events & EVENT_SET_FLAG) != 0) {
- ctx->flag = true;
- }
-
- if ((events & EVENT_WAKEUP_MASTER) != 0) {
- send_events(ctx->master, EVENT_WAKEUP_MASTER);
- }
- }
-}
-
-static void busy_task(rtems_task_argument arg)
-{
- (void) arg;
-
- _CPU_Thread_Idle_body(0);
-}
-
-static const char *blocked_or_ready(bool blocked)
-{
- return blocked ? "blocked" : "ready";
-}
-
-static void reconfigure_scheduler(test_context *ctx)
-{
- rtems_status_code sc;
-
- puts("reconfigure scheduler");
-
- set_prio(ctx->master, PRIO_MIDDLE);
- set_prio(ctx->event, PRIO_LOW);
- set_prio(ctx->event_2, PRIO_VERY_LOW);
- set_prio(ctx->busy, PRIO_IDLE);
-
- set_affinity(ctx->master, 0);
- set_affinity(ctx->event, 0);
- set_affinity(ctx->event_2, 0);
- set_affinity(ctx->busy, 0);
-
- sc = rtems_scheduler_remove_processor(ctx->sched_a, 1);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- sc = rtems_scheduler_add_processor(ctx->sched_b, 1);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-}
-
-static void test_simple_pin_unpin(test_context *ctx, int run)
-{
- Per_CPU_Control *cpu_self;
- Thread_Control *executing;
-
- printf("test simple wait unpin (run %i)\n", run);
-
- set_affinity(ctx->busy, 0);
- set_prio(ctx->busy, PRIO_IDLE);
- set_prio(RTEMS_SELF, PRIO_MIDDLE);
- rtems_test_assert(rtems_scheduler_get_processor() == 1);
-
- cpu_self = _Thread_Dispatch_disable();
- executing = _Per_CPU_Get_executing(cpu_self);
- _Thread_Pin(executing);
-
- rtems_test_assert(rtems_scheduler_get_processor() == 1);
-
- _Thread_Unpin(executing, cpu_self);
- _Thread_Dispatch_enable(cpu_self);
-
- rtems_test_assert(rtems_scheduler_get_processor() == 1);
-}
-
-static void test_pin_wait_unpin(test_context *ctx, bool blocked, int run)
-{
- printf("test pin wait unpin (%s, run %i)\n", blocked_or_ready(blocked), run);
-
- set_affinity(ctx->busy, 0);
- set_prio(ctx->busy, PRIO_IDLE);
- set_prio(RTEMS_SELF, PRIO_MIDDLE);
- set_prio(ctx->event, PRIO_LOW);
- set_affinity(ctx->event, 1);
- rtems_test_assert(rtems_scheduler_get_processor() == 1);
-
- pin(blocked);
- rtems_test_assert(rtems_scheduler_get_processor() == 1);
-
- send_events(ctx->event, EVENT_WAKEUP_MASTER);
- rtems_test_assert(rtems_scheduler_get_processor() == 1);
- wait_for_events();
- rtems_test_assert(rtems_scheduler_get_processor() == 1);
-
- set_prio(ctx->busy, PRIO_HIGH);
- set_affinity(ctx->busy, 0);
- unpin(blocked);
- rtems_test_assert(rtems_scheduler_get_processor() == 1);
-}
-
-static void test_pin_preempt_unpin(test_context *ctx, bool blocked, int run)
-{
- printf(
- "test pin preempt unpin (%s, run %i)\n",
- blocked_or_ready(blocked),
- run
- );
-
- set_prio(RTEMS_SELF, PRIO_MIDDLE);
- set_prio(ctx->event, PRIO_VERY_HIGH);
- set_prio(ctx->busy, PRIO_HIGH);
- set_affinity(ctx->event, 0);
- set_affinity(ctx->busy, 0);
- rtems_test_assert(rtems_scheduler_get_processor() == 1);
-
- pin(blocked);
- rtems_test_assert(rtems_scheduler_get_processor() == 1);
-
- ctx->flag = false;
- send_events(
- ctx->event,
- EVENT_MOVE_BUSY_TO_CPU_1 | EVENT_SET_SELF_PRIO_TO_LOW
- | EVENT_SET_BUSY_PRIO_TO_IDLE | EVENT_SET_FLAG
- );
-
- while (!ctx->flag) {
- rtems_test_assert(rtems_scheduler_get_processor() == 1);
- }
-
- set_affinity(ctx->busy, 0);
- unpin(blocked);
- rtems_test_assert(rtems_scheduler_get_processor() == 1);
-}
-
-static void test_pin_home_no_help_unpin(
- test_context *ctx,
- bool blocked,
- int run
-)
-{
- rtems_status_code sc;
-
- printf(
- "test pin home no help unpin (%s, run %i)\n",
- blocked_or_ready(blocked),
- run
- );
-
- set_affinity(ctx->busy, 1);
- set_prio(ctx->busy, PRIO_IDLE);
- set_prio(RTEMS_SELF, PRIO_MIDDLE);
- rtems_test_assert(rtems_scheduler_get_processor() == 0);
-
- pin(blocked);
- rtems_test_assert(rtems_scheduler_get_processor() == 0);
-
- sc = rtems_task_set_scheduler(RTEMS_SELF, ctx->sched_b, 1);
- rtems_test_assert(sc == RTEMS_RESOURCE_IN_USE);
-
- rtems_mutex_lock(&ctx->mtx);
- rtems_test_assert(rtems_scheduler_get_processor() == 0);
-
- set_affinity(ctx->event, 1);
- set_prio(ctx->event, PRIO_MIDDLE);
-
- send_events(ctx->event, EVENT_MTX_LOCK);
- set_prio(ctx->event_2, PRIO_LOW);
- set_affinity(ctx->event_2, 1);
- send_events(ctx->event_2, EVENT_WAKEUP_MASTER);
- wait_for_events();
-
- /* Now the event task can help us */
- rtems_test_assert(ctx->mtx._Queue._heads != NULL);
- rtems_test_assert(rtems_scheduler_get_processor() == 0);
-
- set_affinity(ctx->event_2, 0);
- set_affinity(ctx->busy, 1);
- set_prio(ctx->busy, PRIO_HIGH);
- send_events(
- ctx->event_2,
- EVENT_MOVE_BUSY_TO_CPU_0 | EVENT_MOVE_SELF_TO_CPU_1
- | EVENT_SET_SELF_PRIO_TO_LOW | EVENT_SET_BUSY_PRIO_TO_IDLE
- );
- set_prio(ctx->event_2, PRIO_VERY_HIGH);
- rtems_test_assert(rtems_scheduler_get_processor() == 0);
-
- rtems_mutex_unlock(&ctx->mtx);
- rtems_test_assert(rtems_scheduler_get_processor() == 0);
-
- send_events(ctx->event, EVENT_WAKEUP_MASTER | EVENT_MTX_UNLOCK);
- wait_for_events();
- rtems_test_assert(rtems_scheduler_get_processor() == 0);
-
- unpin(blocked);
- rtems_test_assert(rtems_scheduler_get_processor() == 0);
-}
-
-static void test_pin_foreign_no_help_unpin(
- test_context *ctx,
- bool blocked,
- int run
-)
-{
- printf(
- "test pin foreign no help unpin (%s, run %i)\n",
- blocked_or_ready(blocked),
- run
- );
-
- set_affinity(ctx->busy, 1);
- set_prio(ctx->busy, PRIO_IDLE);
- set_prio(RTEMS_SELF, PRIO_MIDDLE);
- rtems_test_assert(rtems_scheduler_get_processor() == 0);
-
- rtems_mutex_lock(&ctx->mtx);
- rtems_test_assert(rtems_scheduler_get_processor() == 0);
-
- set_affinity(ctx->event, 1);
- set_prio(ctx->event, PRIO_MIDDLE);
- send_events(ctx->event, EVENT_MTX_LOCK);
- set_prio(ctx->event_2, PRIO_LOW);
- set_affinity(ctx->event_2, 1);
- send_events(ctx->event_2, EVENT_WAKEUP_MASTER);
- wait_for_events();
-
- /* Now the event task can help us */
- rtems_test_assert(ctx->mtx._Queue._heads != NULL);
- rtems_test_assert(rtems_scheduler_get_processor() == 0);
-
- /* Request help */
- set_affinity(ctx->busy, 0);
- set_prio(ctx->busy, PRIO_HIGH);
- rtems_test_assert(rtems_scheduler_get_processor() == 1);
-
- /* Pin while using foreign scheduler */
- pin(blocked);
- rtems_test_assert(rtems_scheduler_get_processor() == 1);
-
- set_affinity(ctx->event_2, 1);
- send_events(
- ctx->event_2,
- EVENT_MOVE_BUSY_TO_CPU_1 | EVENT_MOVE_SELF_TO_CPU_0
- | EVENT_SET_SELF_PRIO_TO_LOW | EVENT_SET_BUSY_PRIO_TO_IDLE
- );
- set_prio(ctx->event_2, PRIO_VERY_HIGH);
- rtems_test_assert(rtems_scheduler_get_processor() == 1);
-
- unpin(blocked);
- rtems_test_assert(rtems_scheduler_get_processor() == 0);
-
- set_prio(ctx->busy, PRIO_IDLE);
- rtems_mutex_unlock(&ctx->mtx);
- rtems_test_assert(rtems_scheduler_get_processor() == 0);
-
- send_events(ctx->event, EVENT_WAKEUP_MASTER | EVENT_MTX_UNLOCK);
- wait_for_events();
- rtems_test_assert(rtems_scheduler_get_processor() == 0);
-}
-
-static void test(test_context *ctx)
-{
- rtems_status_code sc;
- int run;
-
- ctx->master = rtems_task_self();
-
- rtems_mutex_init(&ctx->mtx, "test");
-
- sc = rtems_scheduler_ident(SCHED_A, &ctx->sched_a);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- sc = rtems_scheduler_ident(SCHED_B, &ctx->sched_b);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- sc = rtems_task_create(
- rtems_build_name('B', 'U', 'S', 'Y'),
- PRIO_HIGH,
- RTEMS_MINIMUM_STACK_SIZE,
- RTEMS_DEFAULT_MODES,
- RTEMS_DEFAULT_ATTRIBUTES,
- &ctx->busy
- );
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- sc = rtems_task_start(ctx->busy, busy_task, (rtems_task_argument) ctx);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- set_affinity(ctx->busy, 0);
- set_prio(ctx->busy, PRIO_IDLE);
- rtems_test_assert(rtems_scheduler_get_processor() == 1);
-
- sc = rtems_task_create(
- rtems_build_name('E', 'V', 'T', '1'),
- PRIO_LOW,
- RTEMS_MINIMUM_STACK_SIZE,
- RTEMS_DEFAULT_MODES,
- RTEMS_DEFAULT_ATTRIBUTES,
- &ctx->event
- );
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- sc = rtems_task_start(ctx->event, event_task, (rtems_task_argument) ctx);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- send_events(ctx->event, EVENT_WAKEUP_MASTER);
- wait_for_events();
-
- sc = rtems_task_create(
- rtems_build_name('E', 'V', 'T', '2'),
- PRIO_LOW,
- RTEMS_MINIMUM_STACK_SIZE,
- RTEMS_DEFAULT_MODES,
- RTEMS_DEFAULT_ATTRIBUTES,
- &ctx->event_2
- );
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- sc = rtems_task_start(ctx->event_2, event_task, (rtems_task_argument) ctx);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
-
- send_events(ctx->event_2, EVENT_WAKEUP_MASTER);
- wait_for_events();
-
- for (run = 1; run <= 3; ++run) {
- test_simple_pin_unpin(ctx, run);
- test_pin_wait_unpin(ctx, true, run);
- test_pin_wait_unpin(ctx, false, run);
- test_pin_preempt_unpin(ctx, true, run);
- test_pin_preempt_unpin(ctx, false, run);
- }
-
- reconfigure_scheduler(ctx);
-
- for (run = 1; run <= 3; ++run) {
- test_pin_home_no_help_unpin(ctx, true, run);
- test_pin_home_no_help_unpin(ctx, false, run);
- test_pin_foreign_no_help_unpin(ctx, true, run);
- test_pin_foreign_no_help_unpin(ctx, false, run);
- }
-}
-
-static void Init(rtems_task_argument arg)
-{
- TEST_BEGIN();
-
- if (rtems_scheduler_get_processor_maximum() == CPU_COUNT) {
- test(&test_instance);
- } else {
- puts("warning: wrong processor count to run the test");
- }
-
- TEST_END();
- rtems_test_exit(0);
-}
-
-#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
-#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
-
-#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
-
-#define CONFIGURE_MAXIMUM_PROCESSORS CPU_COUNT
-
-#define CONFIGURE_MAXIMUM_TASKS 4
-
-#define CONFIGURE_INIT_TASK_PRIORITY PRIO_MIDDLE
-
-#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
-
#define CONFIGURE_SCHEDULER_EDF_SMP
#include <rtems/scheduler.h>
@@ -603,7 +26,7 @@ RTEMS_SCHEDULER_EDF_SMP(b);
#define CONFIGURE_SCHEDULER_TABLE_ENTRIES \
RTEMS_SCHEDULER_TABLE_EDF_SMP(a, SCHED_A), \
- RTEMS_SCHEDULER_TABLE_EDF_SMP(b, SCHED_B) \
+ RTEMS_SCHEDULER_TABLE_EDF_SMP(b, SCHED_B)
#define CONFIGURE_SCHEDULER_ASSIGNMENTS \
RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
diff --git a/testsuites/smptests/smpthreadpin02/init.c b/testsuites/smptests/smpthreadpin02/init.c
new file mode 100644
index 0000000..fe9e0aa
--- /dev/null
+++ b/testsuites/smptests/smpthreadpin02/init.c
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @brief Tests pinning with the SMP priority affinity scheduler.
+ */
+
+/*
+ * Copyright (C) 2021 On-Line Applications Research Corporation (OAR).
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <smpthreadpin.h>
+
+const char rtems_test_name[] = "SMPTHREADPIN 2";
+
+#define CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP
+
+#include <rtems/scheduler.h>
+
+RTEMS_SCHEDULER_PRIORITY_AFFINITY_SMP(a, 8);
+
+RTEMS_SCHEDULER_PRIORITY_AFFINITY_SMP(b, 8);
+
+#define CONFIGURE_SCHEDULER_TABLE_ENTRIES \
+ RTEMS_SCHEDULER_TABLE_PRIORITY_AFFINITY_SMP(a, SCHED_A), \
+ RTEMS_SCHEDULER_TABLE_PRIORITY_AFFINITY_SMP(b, SCHED_B)
+
+#define CONFIGURE_SCHEDULER_ASSIGNMENTS \
+ RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
+ RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL)
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/smptests/smpthreadpin02/smpthreadpin02.doc b/testsuites/smptests/smpthreadpin02/smpthreadpin02.doc
new file mode 100644
index 0000000..e306137
--- /dev/null
+++ b/testsuites/smptests/smpthreadpin02/smpthreadpin02.doc
@@ -0,0 +1,12 @@
+This file describes the directives and concepts tested by this test set.
+
+test set name: smpthreadpin02
+
+directives:
+
+ - _Thread_Pin()
+ - _Thread_Unpin()
+
+concepts:
+
+ - Ensure that the thread to processor pinning works.
diff --git a/testsuites/smptests/smpthreadpin02/smpthreadpin02.scn b/testsuites/smptests/smpthreadpin02/smpthreadpin02.scn
new file mode 100644
index 0000000..d0b1543
--- /dev/null
+++ b/testsuites/smptests/smpthreadpin02/smpthreadpin02.scn
@@ -0,0 +1,35 @@
+*** BEGIN OF TEST SMPTHREADPIN 2 ***
+*** TEST VERSION: 6.0.0.53a292448f4f064151a3b49f41e43a35aa69dcc2
+*** TEST STATE: EXPECTED_PASS
+*** TEST BUILD: RTEMS_POSIX_API RTEMS_SMP
+*** TEST TOOLS: 10.3.1 20210409 (RTEMS 6, RSB e845bd5becd4328dc42db3377d44138e23b0d1f7, Newlib eb03ac1)
+test simple wait unpin (run 1)
+test pin wait unpin (blocked, run 1)
+test pin wait unpin (ready, run 1)
+test pin preempt unpin (blocked, run 1)
+test pin preempt unpin (ready, run 1)
+test simple wait unpin (run 2)
+test pin wait unpin (blocked, run 2)
+test pin wait unpin (ready, run 2)
+test pin preempt unpin (blocked, run 2)
+test pin preempt unpin (ready, run 2)
+test simple wait unpin (run 3)
+test pin wait unpin (blocked, run 3)
+test pin wait unpin (ready, run 3)
+test pin preempt unpin (blocked, run 3)
+test pin preempt unpin (ready, run 3)
+reconfigure scheduler
+test pin home no help unpin (blocked, run 1)
+test pin home no help unpin (ready, run 1)
+test pin foreign no help unpin (blocked, run 1)
+test pin foreign no help unpin (ready, run 1)
+test pin home no help unpin (blocked, run 2)
+test pin home no help unpin (ready, run 2)
+test pin foreign no help unpin (blocked, run 2)
+test pin foreign no help unpin (ready, run 2)
+test pin home no help unpin (blocked, run 3)
+test pin home no help unpin (ready, run 3)
+test pin foreign no help unpin (blocked, run 3)
+test pin foreign no help unpin (ready, run 3)
+
+*** END OF TEST SMPTHREADPIN 2 ***
--
1.8.3.1
More information about the devel
mailing list