summaryrefslogtreecommitdiffstats
path: root/testsuites/smptests/smpscheduler02/init.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-04-09 15:07:54 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-04-15 10:41:44 +0200
commitc5831a3f9af11228dbdaabaf01f69d37e55684ef (patch)
treee9ddedd942f3f31d239820dfc4dbcef4cde0b09a /testsuites/smptests/smpscheduler02/init.c
parentrtems: Add task get/set scheduler (diff)
downloadrtems-c5831a3f9af11228dbdaabaf01f69d37e55684ef.tar.bz2
score: Add clustered/partitioned scheduling
Clustered/partitioned scheduling helps to control the worst-case latencies in the system. The goal is to reduce the amount of shared state in the system and thus prevention of lock contention. Modern multi-processor systems tend to have several layers of data and instruction caches. With clustered/partitioned scheduling it is possible to honour the cache topology of a system and thus avoid expensive cache synchronization traffic. We have clustered scheduling in case the set of processors of a system is partitioned into non-empty pairwise-disjoint subsets. These subsets are called clusters. Clusters with a cardinality of one are partitions. Each cluster is owned by exactly one scheduler instance.
Diffstat (limited to 'testsuites/smptests/smpscheduler02/init.c')
-rw-r--r--testsuites/smptests/smpscheduler02/init.c222
1 files changed, 222 insertions, 0 deletions
diff --git a/testsuites/smptests/smpscheduler02/init.c b/testsuites/smptests/smpscheduler02/init.c
new file mode 100644
index 0000000000..f958744415
--- /dev/null
+++ b/testsuites/smptests/smpscheduler02/init.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@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/libcsupport.h>
+
+#include "tmacros.h"
+
+const char rtems_test_name[] = "SMPSCHEDULER 2";
+
+#if defined(__RTEMS_HAVE_SYS_CPUSET_H__)
+
+#define CPU_COUNT 2
+
+#define SCHED_A rtems_build_name(' ', ' ', ' ', 'A')
+
+#define SCHED_B rtems_build_name(' ', ' ', ' ', 'B')
+
+static rtems_id main_task_id;
+
+static void task(rtems_task_argument arg)
+{
+ rtems_status_code sc;
+
+ (void) arg;
+
+ rtems_test_assert(rtems_get_current_processor() == 1);
+
+ sc = rtems_event_transient_send(main_task_id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ while (1) {
+ /* Do nothing */
+ }
+}
+
+static void test(void)
+{
+ rtems_status_code sc;
+ rtems_id task_id;
+ rtems_id scheduler_id;
+ rtems_id scheduler_a_id;
+ rtems_id scheduler_b_id;
+ cpu_set_t cpuset;
+ cpu_set_t first_cpu;
+ cpu_set_t second_cpu;
+ cpu_set_t all_cpus;
+
+ main_task_id = rtems_task_self();
+
+ CPU_ZERO(&first_cpu);
+ CPU_SET(0, &first_cpu);
+
+ CPU_ZERO(&second_cpu);
+ CPU_SET(1, &second_cpu);
+
+ CPU_ZERO(&all_cpus);
+ CPU_SET(0, &all_cpus);
+ CPU_SET(1, &all_cpus);
+
+ rtems_test_assert(rtems_get_current_processor() == 0);
+
+ sc = rtems_scheduler_ident(SCHED_A, &scheduler_a_id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_scheduler_ident(SCHED_B, &scheduler_b_id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+ rtems_test_assert(scheduler_a_id != scheduler_b_id);
+
+ CPU_ZERO(&cpuset);
+ sc = rtems_scheduler_get_processor_set(
+ scheduler_a_id,
+ sizeof(cpuset),
+ &cpuset
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+ rtems_test_assert(CPU_EQUAL(&cpuset, &first_cpu));
+
+ CPU_ZERO(&cpuset);
+ sc = rtems_scheduler_get_processor_set(
+ scheduler_b_id,
+ sizeof(cpuset),
+ &cpuset
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+ rtems_test_assert(CPU_EQUAL(&cpuset, &second_cpu));
+
+ sc = rtems_task_create(
+ rtems_build_name('T', 'A', 'S', 'K'),
+ 1,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &task_id
+ );
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_get_scheduler(task_id, &scheduler_id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+ rtems_test_assert(scheduler_id == scheduler_a_id);
+
+ CPU_ZERO(&cpuset);
+ sc = rtems_task_get_affinity(task_id, sizeof(cpuset), &cpuset);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+ rtems_test_assert(CPU_EQUAL(&cpuset, &first_cpu));
+
+ sc = rtems_task_set_scheduler(task_id, scheduler_b_id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_get_scheduler(task_id, &scheduler_id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+ rtems_test_assert(scheduler_id == scheduler_b_id);
+
+ CPU_ZERO(&cpuset);
+ sc = rtems_task_get_affinity(task_id, sizeof(cpuset), &cpuset);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+ rtems_test_assert(CPU_EQUAL(&cpuset, &second_cpu));
+
+ sc = rtems_task_set_affinity(task_id, sizeof(all_cpus), &all_cpus);
+ rtems_test_assert(sc == RTEMS_INVALID_NUMBER);
+
+ sc = rtems_task_set_affinity(task_id, sizeof(first_cpu), &first_cpu);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_get_scheduler(task_id, &scheduler_id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+ rtems_test_assert(scheduler_id == scheduler_a_id);
+
+ sc = rtems_task_set_affinity(task_id, sizeof(second_cpu), &second_cpu);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_get_scheduler(task_id, &scheduler_id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+ rtems_test_assert(scheduler_id == scheduler_b_id);
+
+ sc = rtems_task_start(task_id, task, 0);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_set_scheduler(task_id, scheduler_a_id);
+ rtems_test_assert(sc == RTEMS_INCORRECT_STATE);
+
+ sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+ sc = rtems_task_delete(task_id);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+#else /* defined(__RTEMS_HAVE_SYS_CPUSET_H__) */
+
+static void test(void)
+{
+ /* Nothing to do */
+}
+
+#endif /* defined(__RTEMS_HAVE_SYS_CPUSET_H__) */
+
+static void Init(rtems_task_argument arg)
+{
+ rtems_resource_snapshot snapshot;
+
+ TEST_BEGIN();
+
+ rtems_resource_snapshot_take(&snapshot);
+
+ test();
+
+ rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
+
+ TEST_END();
+ rtems_test_exit(0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_SMP_APPLICATION
+
+#define CONFIGURE_SMP_MAXIMUM_PROCESSORS CPU_COUNT
+
+#define CONFIGURE_MAXIMUM_PRIORITY 255
+
+#define CONFIGURE_SCHEDULER_PRIORITY_SMP
+
+#include <rtems/scheduler.h>
+
+RTEMS_SCHEDULER_CONTEXT_PRIORITY_SMP(a, CONFIGURE_MAXIMUM_PRIORITY + 1);
+
+RTEMS_SCHEDULER_CONTEXT_PRIORITY_SMP(b, CONFIGURE_MAXIMUM_PRIORITY + 1);
+
+#define CONFIGURE_SCHEDULER_CONTROLS \
+ RTEMS_SCHEDULER_CONTROL_PRIORITY_SMP(a, SCHED_A), \
+ RTEMS_SCHEDULER_CONTROL_PRIORITY_SMP(b, SCHED_B)
+
+#define CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS \
+ RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
+ RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY)
+
+#define CONFIGURE_MAXIMUM_TASKS CPU_COUNT
+
+#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>