File indexing completed on 2025-05-11 08:24:44
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 "tmacros.h"
0033
0034 #include <stdio.h>
0035 #include <inttypes.h>
0036
0037 const char rtems_test_name[] = "SMPSWITCHEXTENSION 1";
0038
0039 #define CPU_COUNT 2
0040
0041 #define TOGGLER_COUNT 2
0042
0043 #define EXTENSION_COUNT 3
0044
0045 #define PRIO_STOP 2
0046
0047 #define PRIO_SWITCH 3
0048
0049 #define PRIO_HIGH 4
0050
0051 #define PRIO_NORMAL 5
0052
0053 #define PRIO_LOW 6
0054
0055 typedef struct {
0056 uint32_t toggles;
0057 uint32_t unused_space_for_cache_line_alignment[7];
0058 } test_toggler_counters;
0059
0060 typedef struct {
0061 test_toggler_counters counters[TOGGLER_COUNT];
0062 rtems_id toggler_ids[TOGGLER_COUNT];
0063 rtems_id extension_ids[EXTENSION_COUNT];
0064 uint32_t extension_switches;
0065 uint32_t context_switches[EXTENSION_COUNT];
0066 } test_context;
0067
0068 CPU_STRUCTURE_ALIGNMENT static test_context ctx_instance;
0069
0070 static void switch_0(Thread_Control *executing, Thread_Control *heir)
0071 {
0072 test_context *ctx = &ctx_instance;
0073
0074 (void) executing;
0075 (void) heir;
0076
0077 ++ctx->context_switches[0];
0078 }
0079
0080 static void switch_1(Thread_Control *executing, Thread_Control *heir)
0081 {
0082 test_context *ctx = &ctx_instance;
0083
0084 (void) executing;
0085 (void) heir;
0086
0087 ++ctx->context_switches[1];
0088 }
0089
0090 static void switch_2(Thread_Control *executing, Thread_Control *heir)
0091 {
0092 test_context *ctx = &ctx_instance;
0093
0094 (void) executing;
0095 (void) heir;
0096
0097 ++ctx->context_switches[2];
0098 }
0099
0100 static const rtems_extensions_table extensions[EXTENSION_COUNT] = {
0101 { .thread_switch = switch_0 },
0102 { .thread_switch = switch_1 },
0103 { .thread_switch = switch_2 }
0104 };
0105
0106 static void toggler(rtems_task_argument self)
0107 {
0108 test_context *ctx = &ctx_instance;
0109 test_toggler_counters *counters = &ctx->counters[self];
0110
0111 while (true) {
0112 rtems_status_code sc;
0113
0114 ++counters->toggles;
0115
0116 sc = rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
0117 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0118 }
0119 }
0120
0121 static void switcher(rtems_task_argument self)
0122 {
0123 test_context *ctx = &ctx_instance;
0124
0125 while (true) {
0126 size_t ext_index;
0127 rtems_status_code sc;
0128
0129 ++ctx->extension_switches;
0130
0131 for (ext_index = 0; ext_index < EXTENSION_COUNT; ++ext_index) {
0132 sc = rtems_extension_create(
0133 rtems_build_name('E', 'X', 'T', (char) ('0' + ext_index)),
0134 &extensions[ext_index],
0135 &ctx->extension_ids[ext_index]
0136 );
0137 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0138 }
0139
0140 for (ext_index = 0; ext_index < EXTENSION_COUNT; ++ext_index) {
0141 sc = rtems_extension_delete(ctx->extension_ids[ext_index]);
0142 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0143 }
0144 }
0145 }
0146
0147 static void stopper(rtems_task_argument arg)
0148 {
0149 (void) arg;
0150
0151 while (true) {
0152
0153 }
0154 }
0155
0156 static void test(void)
0157 {
0158 test_context *ctx = &ctx_instance;
0159 rtems_status_code sc;
0160 rtems_task_argument toggler_index;
0161 rtems_id stopper_id;
0162 rtems_id switcher_id;
0163 size_t ext_index;
0164
0165 sc = rtems_task_create(
0166 rtems_build_name('S', 'T', 'O', 'P'),
0167 PRIO_STOP,
0168 RTEMS_MINIMUM_STACK_SIZE,
0169 RTEMS_DEFAULT_MODES,
0170 RTEMS_DEFAULT_ATTRIBUTES,
0171 &stopper_id
0172 );
0173 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0174
0175 sc = rtems_task_create(
0176 rtems_build_name('E', 'X', 'S', 'W'),
0177 PRIO_SWITCH,
0178 RTEMS_MINIMUM_STACK_SIZE,
0179 RTEMS_DEFAULT_MODES,
0180 RTEMS_DEFAULT_ATTRIBUTES,
0181 &switcher_id
0182 );
0183 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0184
0185 for (toggler_index = 0; toggler_index < TOGGLER_COUNT; ++toggler_index) {
0186 sc = rtems_task_create(
0187 rtems_build_name('T', 'O', 'G', (char) ('0' + toggler_index)),
0188 PRIO_NORMAL,
0189 RTEMS_MINIMUM_STACK_SIZE,
0190 RTEMS_DEFAULT_MODES,
0191 RTEMS_DEFAULT_ATTRIBUTES,
0192 &ctx->toggler_ids[toggler_index]
0193 );
0194 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0195 }
0196
0197 for (toggler_index = 0; toggler_index < TOGGLER_COUNT; ++toggler_index) {
0198 sc = rtems_task_start(ctx->toggler_ids[toggler_index], toggler, toggler_index);
0199 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0200 }
0201
0202 sc = rtems_task_start(switcher_id, switcher, 0);
0203 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0204
0205 sc = rtems_task_wake_after(10 * rtems_clock_get_ticks_per_second());
0206 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0207
0208 sc = rtems_task_start(stopper_id, stopper, 0);
0209 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0210
0211 for (toggler_index = 0; toggler_index < TOGGLER_COUNT; ++toggler_index) {
0212 test_toggler_counters *counters = &ctx->counters[toggler_index];
0213
0214 printf(
0215 "toggler %" PRIuPTR "\n"
0216 "\ttoggles %" PRIu32 "\n",
0217 toggler_index,
0218 counters->toggles
0219 );
0220 }
0221
0222 for (ext_index = 0; ext_index < EXTENSION_COUNT; ++ext_index) {
0223 printf(
0224 "extension %" PRIuPTR "\n"
0225 "\tcontext switches %" PRIu32 "\n",
0226 ext_index,
0227 ctx->context_switches[ext_index]
0228 );
0229 }
0230
0231 printf(
0232 "extension switches %" PRIu32 "\n",
0233 ctx->extension_switches
0234 );
0235 }
0236
0237 static void Init(rtems_task_argument arg)
0238 {
0239 TEST_BEGIN();
0240
0241 if (rtems_scheduler_get_processor_maximum() >= 2) {
0242 test();
0243 }
0244
0245 TEST_END();
0246 rtems_test_exit(0);
0247 }
0248
0249 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0250 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0251
0252 #define CONFIGURE_MAXIMUM_PROCESSORS CPU_COUNT
0253
0254 #define CONFIGURE_MAXIMUM_TASKS (3 + TOGGLER_COUNT)
0255
0256 #define CONFIGURE_MAXIMUM_USER_EXTENSIONS EXTENSION_COUNT
0257
0258 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0259
0260 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0261
0262 #define CONFIGURE_INIT
0263
0264 #include <rtems/confdefs.h>