File indexing completed on 2025-05-11 08:24:47
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 #include <rtems/test.h>
0034
0035 #include <rtems/rtems/semimpl.h>
0036
0037 const char rtems_test_name[] = "SPINTRCRITICAL 22";
0038
0039 typedef struct {
0040 rtems_id semaphore_id;
0041 Semaphore_Control *semaphore_control;
0042 Thread_Control *main_task_control;
0043 } test_context;
0044
0045 static Semaphore_Control *get_semaphore_control(rtems_id id)
0046 {
0047 Thread_queue_Context queue_context;
0048 Semaphore_Control *sem;
0049
0050 sem = _Semaphore_Get(id, &queue_context);
0051 rtems_test_assert(sem != NULL);
0052 _ISR_lock_ISR_enable(&queue_context.Lock_context.Lock_context);
0053
0054 return sem;
0055 }
0056
0057 static T_interrupt_test_state release_semaphore(void *arg)
0058 {
0059 test_context *ctx = arg;
0060 rtems_status_code sc;
0061 Thread_Wait_flags flags;
0062 T_interrupt_test_state state;
0063
0064 flags = _Thread_Wait_flags_get(ctx->main_task_control);
0065
0066 if (
0067 flags == (THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_INTEND_TO_BLOCK)
0068 ) {
0069 CORE_semaphore_Control *sem;
0070
0071 state = T_INTERRUPT_TEST_DONE;
0072
0073 sc = rtems_semaphore_release(ctx->semaphore_id);
0074 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0075
0076 rtems_test_assert(
0077 _Thread_Wait_flags_get(ctx->main_task_control)
0078 == THREAD_WAIT_STATE_READY
0079 );
0080 sem = &ctx->semaphore_control->Core_control.Semaphore;
0081 rtems_test_assert(sem->count == 0);
0082 } else {
0083 if (flags == (THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_BLOCKED)) {
0084 state = T_INTERRUPT_TEST_LATE;
0085 } else {
0086 state = T_INTERRUPT_TEST_EARLY;
0087 }
0088
0089 sc = rtems_semaphore_release(ctx->semaphore_id);
0090 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0091 }
0092
0093 return state;
0094 }
0095
0096 static void action(void *arg)
0097 {
0098 test_context *ctx = arg;
0099 rtems_status_code sc;
0100
0101 sc = rtems_semaphore_obtain(
0102 ctx->semaphore_id,
0103 RTEMS_WAIT,
0104 2
0105 );
0106 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0107 }
0108
0109 static void prepare(void *arg)
0110 {
0111 test_context *ctx = arg;
0112 rtems_status_code sc;
0113
0114 sc = rtems_semaphore_obtain(
0115 ctx->semaphore_id,
0116 RTEMS_NO_WAIT,
0117 0
0118 );
0119 rtems_test_assert(sc == RTEMS_SUCCESSFUL || sc == RTEMS_UNSATISFIED);
0120 }
0121
0122 static void blocked(void *arg)
0123 {
0124 test_context *ctx = arg;
0125 rtems_status_code sc;
0126
0127 T_interrupt_test_change_state(
0128 T_INTERRUPT_TEST_ACTION,
0129 T_INTERRUPT_TEST_LATE
0130 );
0131
0132 sc = rtems_semaphore_release(ctx->semaphore_id);
0133 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0134 }
0135
0136 static const T_interrupt_test_config config = {
0137 .prepare = prepare,
0138 .action = action,
0139 .interrupt = release_semaphore,
0140 .blocked = blocked,
0141 .max_iteration_count = 10000
0142 };
0143
0144 T_TEST_CASE(InterruptSemaphoreObtain)
0145 {
0146 test_context ctx;
0147 rtems_status_code sc;
0148 T_interrupt_test_state state;
0149
0150 ctx.main_task_control = _Thread_Get_executing();
0151
0152 sc = rtems_semaphore_create(
0153 rtems_build_name('S', 'E', 'M', 'A'),
0154 1,
0155 RTEMS_SIMPLE_BINARY_SEMAPHORE,
0156 0,
0157 &ctx.semaphore_id
0158 );
0159 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0160
0161 ctx.semaphore_control = get_semaphore_control(ctx.semaphore_id);
0162
0163 state = T_interrupt_test(&config, &ctx);
0164 T_eq_int(state, T_INTERRUPT_TEST_DONE);
0165
0166 sc = rtems_semaphore_delete(ctx.semaphore_id);
0167 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0168 }
0169
0170 static void Init(rtems_task_argument argument)
0171 {
0172 rtems_test_run(argument, TEST_STATE);
0173 }
0174
0175 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0176 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0177
0178 #define CONFIGURE_MICROSECONDS_PER_TICK 1000
0179
0180 #define CONFIGURE_MAXIMUM_SEMAPHORES 1
0181 #define CONFIGURE_MAXIMUM_TASKS 1
0182
0183 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0184
0185 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0186
0187 #define CONFIGURE_INIT
0188
0189 #include <rtems/confdefs.h>