File indexing completed on 2025-05-11 08:24:50
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 <sched.h>
0033
0034 #include <rtems.h>
0035 #include <rtems/test-info.h>
0036 #include <rtems/thread.h>
0037
0038 #include <tmacros.h>
0039
0040 const char rtems_test_name[] = "TMONETOONE";
0041
0042 typedef enum {
0043 TEST_YIELD,
0044 TEST_EVENTS,
0045 TEST_BSEM,
0046 TEST_CLASSIC_FIFO_BSEM,
0047 TEST_CLASSIC_PRIO_BSEM
0048 } test_variant;
0049
0050 typedef struct {
0051 volatile uint32_t counter;
0052 test_variant variant;
0053 rtems_id task;
0054 rtems_binary_semaphore bsem;
0055 rtems_id classic_fifo_bsem;
0056 rtems_id classic_prio_bsem;
0057 rtems_id other_task;
0058 rtems_binary_semaphore *other_bsem;
0059 rtems_id other_classic_fifo_bsem;
0060 rtems_id other_classic_prio_bsem;
0061 } task_context RTEMS_ALIGNED(CPU_CACHE_LINE_BYTES);
0062
0063 typedef struct {
0064 task_context a;
0065 task_context b;
0066 } test_context;
0067
0068 static test_context test_instance;
0069
0070 static void test_yield(task_context *tc)
0071 {
0072 rtems_event_set events;
0073 uint32_t counter;
0074
0075 (void)rtems_event_receive(
0076 RTEMS_EVENT_0,
0077 RTEMS_WAIT | RTEMS_EVENT_ALL,
0078 RTEMS_NO_TIMEOUT,
0079 &events
0080 );
0081
0082 counter = 0;
0083
0084 while (true) {
0085 (void)sched_yield();
0086 ++counter;
0087 tc->counter = counter;
0088 }
0089 }
0090
0091 static void test_events(task_context *tc)
0092 {
0093 uint32_t counter;
0094 rtems_id other;
0095
0096 counter = 0;
0097 other = tc->other_task;
0098
0099 while (true) {
0100 rtems_event_set events;
0101
0102 (void)rtems_event_receive(
0103 RTEMS_EVENT_0,
0104 RTEMS_WAIT | RTEMS_EVENT_ALL,
0105 RTEMS_NO_TIMEOUT,
0106 &events
0107 );
0108 (void)rtems_event_send(other, RTEMS_EVENT_0);
0109 ++counter;
0110 tc->counter = counter;
0111 }
0112 }
0113
0114 static void test_bsem(task_context *tc)
0115 {
0116 uint32_t counter;
0117 rtems_binary_semaphore *other;
0118
0119 counter = 0;
0120 other = tc->other_bsem;
0121
0122 while (true) {
0123 rtems_binary_semaphore_wait(&tc->bsem);
0124 rtems_binary_semaphore_post(other);
0125 ++counter;
0126 tc->counter = counter;
0127 }
0128 }
0129
0130 static void test_classic_fifo_bsem(task_context *tc)
0131 {
0132 uint32_t counter;
0133 rtems_id own;
0134 rtems_id other;
0135
0136 counter = 0;
0137 own = tc->classic_fifo_bsem;
0138 other = tc->other_classic_fifo_bsem;
0139
0140 while (true) {
0141 (void)rtems_semaphore_obtain(own, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0142 (void)rtems_semaphore_release(other);
0143 ++counter;
0144 tc->counter = counter;
0145 }
0146 }
0147
0148 static void test_classic_prio_bsem(task_context *tc)
0149 {
0150 uint32_t counter;
0151 rtems_id own;
0152 rtems_id other;
0153
0154 counter = 0;
0155 own = tc->classic_prio_bsem;
0156 other = tc->other_classic_prio_bsem;
0157
0158 while (true) {
0159 (void)rtems_semaphore_obtain(own, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0160 (void)rtems_semaphore_release(other);
0161 ++counter;
0162 tc->counter = counter;
0163 }
0164 }
0165
0166 static void worker_task(rtems_task_argument arg)
0167 {
0168 task_context *tc;
0169
0170 tc = (task_context *) arg;
0171
0172 switch (tc->variant) {
0173 case TEST_YIELD:
0174 test_yield(tc);
0175 break;
0176 case TEST_EVENTS:
0177 test_events(tc);
0178 break;
0179 case TEST_BSEM:
0180 test_bsem(tc);
0181 break;
0182 case TEST_CLASSIC_FIFO_BSEM:
0183 test_classic_fifo_bsem(tc);
0184 break;
0185 case TEST_CLASSIC_PRIO_BSEM:
0186 test_classic_prio_bsem(tc);
0187 break;
0188 default:
0189 rtems_test_assert(0);
0190 break;
0191 }
0192 }
0193
0194 static void create_task(task_context *tc)
0195 {
0196 rtems_status_code sc;
0197
0198 rtems_binary_semaphore_init(&tc->bsem, "test");
0199
0200 sc = rtems_semaphore_create(
0201 rtems_build_name('T', 'E', 'S', 'T'),
0202 0,
0203 RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_FIFO,
0204 0,
0205 &tc->classic_fifo_bsem
0206 );
0207 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0208
0209 sc = rtems_semaphore_create(
0210 rtems_build_name('T', 'E', 'S', 'T'),
0211 0,
0212 RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_PRIORITY,
0213 0,
0214 &tc->classic_prio_bsem
0215 );
0216 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0217
0218 sc = rtems_task_create(
0219 rtems_build_name('T', 'E', 'S', 'T'),
0220 2,
0221 RTEMS_MINIMUM_STACK_SIZE,
0222 RTEMS_DEFAULT_MODES,
0223 RTEMS_DEFAULT_ATTRIBUTES,
0224 &tc->task
0225 );
0226 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0227
0228 sc = rtems_task_start(tc->task, worker_task, (rtems_task_argument) tc);
0229 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0230 }
0231
0232 static const char * const variant_names[] = {
0233 "yield",
0234 "event",
0235 "self-contained binary semaphore",
0236 "Classic binary semaphore (FIFO)",
0237 "Classic binary semaphore (priority)"
0238 };
0239
0240 static void prepare(test_context *ctx, test_variant variant)
0241 {
0242 rtems_status_code sc;
0243
0244 printf("%s\n", variant_names[variant]);
0245
0246 ctx->a.variant = variant;
0247 ctx->b.variant = variant;
0248
0249 ctx->a.counter = 0;
0250 ctx->b.counter = 0;
0251
0252 sc = rtems_task_restart(ctx->a.task, (rtems_task_argument) &ctx->a);
0253 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0254
0255 sc = rtems_task_restart(ctx->b.task, (rtems_task_argument) &ctx->b);
0256 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0257
0258 sc = rtems_task_wake_after(2);
0259 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0260 }
0261
0262 static void run(test_context *ctx)
0263 {
0264 rtems_status_code sc;
0265
0266 sc = rtems_task_wake_after(rtems_clock_get_ticks_per_second());
0267 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0268
0269 printf("a %" PRIu32 "\nb %" PRIu32 "\n", ctx->a.counter, ctx->b.counter);
0270 }
0271
0272 static void Init(rtems_task_argument arg)
0273 {
0274 test_context *ctx = &test_instance;
0275 rtems_status_code sc;
0276
0277 TEST_BEGIN();
0278
0279 create_task(&ctx->a);
0280 create_task(&ctx->b);
0281
0282 ctx->a.other_task = ctx->b.task;
0283 ctx->a.other_bsem = &ctx->b.bsem;
0284 ctx->a.other_classic_fifo_bsem = ctx->b.classic_fifo_bsem;
0285 ctx->a.other_classic_prio_bsem = ctx->b.classic_prio_bsem;
0286
0287 ctx->b.other_task = ctx->a.task;
0288 ctx->b.other_bsem = &ctx->a.bsem;
0289 ctx->b.other_classic_fifo_bsem = ctx->a.classic_fifo_bsem;
0290 ctx->b.other_classic_prio_bsem = ctx->a.classic_prio_bsem;
0291
0292 prepare(ctx, TEST_YIELD);
0293
0294 sc = rtems_event_send(ctx->a.task, RTEMS_EVENT_0);
0295 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0296
0297 sc = rtems_event_send(ctx->b.task, RTEMS_EVENT_0);
0298 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0299
0300 run(ctx);
0301 prepare(ctx, TEST_EVENTS);
0302
0303 sc = rtems_event_send(ctx->a.task, RTEMS_EVENT_0);
0304 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0305
0306 run(ctx);
0307 prepare(ctx, TEST_BSEM);
0308
0309 rtems_binary_semaphore_post(&ctx->a.bsem);
0310
0311 run(ctx);
0312 prepare(ctx, TEST_CLASSIC_FIFO_BSEM);
0313
0314 sc = rtems_semaphore_release(ctx->a.classic_fifo_bsem);
0315 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0316
0317 run(ctx);
0318 prepare(ctx, TEST_CLASSIC_PRIO_BSEM);
0319
0320 sc = rtems_semaphore_release(ctx->a.classic_prio_bsem);
0321 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0322
0323 run(ctx);
0324
0325 TEST_END();
0326 rtems_test_exit(0);
0327 }
0328
0329 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0330 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0331
0332 #define CONFIGURE_MAXIMUM_TASKS 3
0333
0334 #define CONFIGURE_MAXIMUM_SEMAPHORES 4
0335
0336 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0337
0338 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0339
0340 #define CONFIGURE_INIT
0341
0342 #include <rtems/confdefs.h>