File indexing completed on 2025-05-11 08:24:43
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031
0032 #include <rtems.h>
0033 #include <rtems/score/threadimpl.h>
0034
0035 #include "tmacros.h"
0036
0037 const char rtems_test_name[] = "SMPSCHEDULER 1";
0038
0039 #define CPU_COUNT 2
0040
0041 #define TASK_COUNT 4
0042
0043 #define FIRST_TASK_PRIORITY 1
0044
0045 #define SECOND_TASK_READY RTEMS_EVENT_0
0046
0047 static rtems_id task_ids[TASK_COUNT];
0048
0049 static void suspend(size_t i)
0050 {
0051 rtems_status_code sc = rtems_task_suspend(task_ids[i]);
0052 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0053 }
0054
0055 static void resume(size_t i)
0056 {
0057 rtems_status_code sc = rtems_task_resume(task_ids[i]);
0058 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0059 }
0060
0061 static void task(rtems_task_argument arg)
0062 {
0063 rtems_task_priority task_priority;
0064 rtems_status_code sc;
0065
0066 sc = rtems_task_set_priority(
0067 RTEMS_SELF,
0068 RTEMS_CURRENT_PRIORITY,
0069 &task_priority
0070 );
0071 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0072
0073 if (arg == 1) {
0074 sc = rtems_event_send(task_ids[0], SECOND_TASK_READY);
0075 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0076 }
0077
0078 while (true) {
0079
0080 }
0081 }
0082
0083 static bool is_per_cpu_state_ok(void)
0084 {
0085 bool ok = true;
0086 uint32_t n = rtems_scheduler_get_processor_maximum();
0087 uint32_t i;
0088
0089 for (i = 0; i < n; ++i) {
0090 const Thread_Control *thread = _Per_CPU_Get_by_index(i)->executing;
0091 uint32_t count = 0;
0092 uint32_t j;
0093
0094 for (j = 0; j < n; ++j) {
0095 const Per_CPU_Control *cpu = _Per_CPU_Get_by_index(j);
0096 const Thread_Control *executing = cpu->executing;
0097 const Thread_Control *heir = cpu->heir;
0098
0099 if (i != j) {
0100 count += executing == thread;
0101 count += heir == thread;
0102 } else {
0103 ++count;
0104 }
0105
0106 ok = ok && _Thread_Get_CPU( executing ) == cpu;
0107 ok = ok && _Thread_Get_CPU( heir ) == cpu;
0108 }
0109
0110 ok = ok && (count == 1);
0111 }
0112
0113 return ok;
0114 }
0115
0116 static void test_scheduler_cross(void)
0117 {
0118 bool per_cpu_state_ok;
0119 Per_CPU_Control *cpu_self;
0120
0121 cpu_self = _Thread_Dispatch_disable();
0122
0123 suspend(0);
0124 suspend(1);
0125 resume(0);
0126 resume(1);
0127
0128 per_cpu_state_ok = is_per_cpu_state_ok();
0129
0130 _Thread_Dispatch_enable( cpu_self );
0131
0132 rtems_test_assert(per_cpu_state_ok);
0133 }
0134
0135 static void test_scheduler_move_heir(void)
0136 {
0137 bool per_cpu_state_ok;
0138 Per_CPU_Control *cpu_self;
0139
0140 cpu_self = _Thread_Dispatch_disable();
0141
0142 suspend(2);
0143 suspend(3);
0144 suspend(0);
0145 resume(2);
0146 suspend(1);
0147 resume(3);
0148 resume(0);
0149
0150 per_cpu_state_ok = is_per_cpu_state_ok();
0151
0152 resume(1);
0153
0154 _Thread_Dispatch_enable( cpu_self );
0155
0156 rtems_test_assert(per_cpu_state_ok);
0157 }
0158
0159 static void test(void)
0160 {
0161 rtems_event_set events;
0162 rtems_status_code sc;
0163 rtems_task_argument task_index;
0164
0165 task_ids[0] = rtems_task_self();
0166
0167 for (task_index = 1; task_index < TASK_COUNT; ++task_index) {
0168 rtems_id task_id;
0169
0170 sc = rtems_task_create(
0171 rtems_build_name('T', 'A', 'S', 'K'),
0172 FIRST_TASK_PRIORITY + task_index,
0173 RTEMS_MINIMUM_STACK_SIZE,
0174 RTEMS_DEFAULT_MODES,
0175 RTEMS_DEFAULT_ATTRIBUTES,
0176 &task_id
0177 );
0178 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0179
0180 sc = rtems_task_start(task_id, task, task_index);
0181 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0182
0183 task_ids[task_index] = task_id;
0184 }
0185
0186 sc = rtems_event_receive(
0187 SECOND_TASK_READY,
0188 RTEMS_EVENT_ALL | RTEMS_WAIT,
0189 RTEMS_NO_TIMEOUT,
0190 &events
0191 );
0192 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0193 rtems_test_assert(events == SECOND_TASK_READY);
0194
0195 test_scheduler_cross();
0196 test_scheduler_move_heir();
0197 }
0198
0199 static void Init(rtems_task_argument arg)
0200 {
0201 TEST_BEGIN();
0202
0203 test();
0204
0205 TEST_END();
0206 rtems_test_exit(0);
0207 }
0208
0209 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0210 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0211
0212 #define CONFIGURE_MAXIMUM_PROCESSORS CPU_COUNT
0213
0214 #define CONFIGURE_MAXIMUM_TASKS TASK_COUNT
0215
0216
0217 #define CONFIGURE_SCHEDULER_SIMPLE_SMP
0218
0219 #define CONFIGURE_INIT_TASK_PRIORITY FIRST_TASK_PRIORITY
0220 #define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
0221 #define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_DEFAULT_ATTRIBUTES
0222
0223 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0224
0225 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0226
0227 #define CONFIGURE_INIT
0228
0229 #include <rtems/confdefs.h>