File indexing completed on 2025-05-11 08:24:42
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 <rtems.h>
0035 #include <rtems/libcsupport.h>
0036 #include <rtems/score/percpu.h>
0037 #include <rtems/score/smpbarrier.h>
0038
0039 #include <test_support.h>
0040
0041 #define CPU_COUNT 2
0042
0043 #define SCHEDULER_A rtems_build_name(' ', ' ', ' ', 'A')
0044
0045 #define SCHEDULER_B rtems_build_name(' ', ' ', ' ', 'B')
0046
0047 const char rtems_test_name[] = "SMPCLOCK 1";
0048
0049 typedef struct {
0050 SMP_barrier_Control barrier;
0051 SMP_barrier_State delay_barrier_state;
0052 SMP_barrier_State timer_barrier_state;
0053 } test_context;
0054
0055 static test_context test_instance = {
0056 .barrier = SMP_BARRIER_CONTROL_INITIALIZER,
0057 .delay_barrier_state = SMP_BARRIER_STATE_INITIALIZER,
0058 .timer_barrier_state = SMP_BARRIER_STATE_INITIALIZER
0059 };
0060
0061 static void wait(test_context *ctx, SMP_barrier_State *bs)
0062 {
0063 _SMP_barrier_Wait(&ctx->barrier, bs, CPU_COUNT);
0064 }
0065
0066 static void timer_isr(rtems_id id, void *arg)
0067 {
0068 test_context *ctx = arg;
0069
0070
0071 wait(ctx, &ctx->timer_barrier_state);
0072 }
0073
0074 static void timer_task(rtems_task_argument arg)
0075 {
0076 test_context *ctx = (test_context *) arg;
0077 rtems_status_code sc;
0078 rtems_id timer_id;
0079
0080 rtems_test_assert(rtems_scheduler_get_processor() == 1);
0081
0082 sc = rtems_timer_create(SCHEDULER_B, &timer_id);
0083 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0084
0085
0086 wait(ctx, &ctx->timer_barrier_state);
0087
0088 sc = rtems_timer_fire_after(timer_id, 1, timer_isr, ctx);
0089 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0090
0091 sc = rtems_task_wake_after(1);
0092 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0093
0094 sc = rtems_timer_delete(timer_id);
0095 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0096
0097
0098 wait(ctx, &ctx->timer_barrier_state);
0099
0100 while (true) {
0101
0102 }
0103 }
0104
0105 static void delay_clock_tick(test_context *ctx)
0106 {
0107 rtems_interrupt_level level;
0108 const Per_CPU_Control *cpu_self = _Per_CPU_Get_by_index(0);
0109 const Per_CPU_Control *cpu_other = _Per_CPU_Get_by_index(1);
0110 uint64_t ticks;
0111
0112 rtems_test_assert(rtems_scheduler_get_processor() == 0);
0113
0114 rtems_test_spin_until_next_tick();
0115 ticks = cpu_self->Watchdog.ticks;
0116
0117 rtems_interrupt_local_disable(level);
0118
0119
0120 wait(ctx, &ctx->delay_barrier_state);
0121
0122
0123 wait(ctx, &ctx->delay_barrier_state);
0124
0125 rtems_test_assert(cpu_self->Watchdog.ticks == ticks);
0126 rtems_test_assert(cpu_other->Watchdog.ticks == ticks + 1);
0127
0128 rtems_interrupt_local_enable(level);
0129
0130 rtems_test_assert(cpu_self->Watchdog.ticks == ticks + 1);
0131 rtems_test_assert(cpu_other->Watchdog.ticks == ticks + 1);
0132
0133
0134 wait(ctx, &ctx->delay_barrier_state);
0135 }
0136
0137 static void test(void)
0138 {
0139 test_context *ctx = &test_instance;
0140 rtems_status_code sc;
0141 rtems_id scheduler_b_id;
0142 rtems_id task_id;
0143
0144 sc = rtems_scheduler_ident(SCHEDULER_B, &scheduler_b_id);
0145 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0146
0147 sc = rtems_task_create(
0148 SCHEDULER_B,
0149 255,
0150 RTEMS_MINIMUM_STACK_SIZE,
0151 RTEMS_DEFAULT_MODES,
0152 RTEMS_DEFAULT_ATTRIBUTES,
0153 &task_id
0154 );
0155 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0156
0157 sc = rtems_task_set_scheduler(task_id, scheduler_b_id, 1);
0158 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0159
0160 sc = rtems_task_start(task_id, timer_task, (rtems_task_argument) ctx);
0161 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0162
0163 delay_clock_tick(ctx);
0164
0165 sc = rtems_task_delete(task_id);
0166 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0167 }
0168
0169 static void Init(rtems_task_argument arg)
0170 {
0171 rtems_resource_snapshot snapshot;
0172
0173 TEST_BEGIN();
0174
0175 rtems_resource_snapshot_take(&snapshot);
0176
0177 if (rtems_scheduler_get_processor_maximum() == CPU_COUNT) {
0178 test();
0179 }
0180
0181 rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
0182
0183 TEST_END();
0184 rtems_test_exit(0);
0185 }
0186
0187 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0188 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0189
0190 #define CONFIGURE_MAXIMUM_PROCESSORS CPU_COUNT
0191
0192 #define CONFIGURE_SCHEDULER_SIMPLE_SMP
0193
0194 #include <rtems/scheduler.h>
0195
0196 RTEMS_SCHEDULER_SIMPLE_SMP(a);
0197 RTEMS_SCHEDULER_SIMPLE_SMP(b);
0198
0199 #define CONFIGURE_SCHEDULER_TABLE_ENTRIES \
0200 RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(a, SCHEDULER_A), \
0201 RTEMS_SCHEDULER_TABLE_SIMPLE_SMP(b, SCHEDULER_B)
0202
0203 #define CONFIGURE_SCHEDULER_ASSIGNMENTS \
0204 RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
0205 RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL)
0206
0207 #define CONFIGURE_MAXIMUM_TASKS CPU_COUNT
0208
0209 #define CONFIGURE_MAXIMUM_TIMERS 1
0210
0211 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0212
0213 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0214
0215 #define CONFIGURE_INIT
0216
0217 #include <rtems/confdefs.h>