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
0029
0030
0031 #ifdef HAVE_CONFIG_H
0032 #include "config.h"
0033 #endif
0034
0035 #include <rtems/test.h>
0036 #include <rtems/test-info.h>
0037
0038 #include <rtems/score/threadimpl.h>
0039
0040 const char rtems_test_name[] = "SPINTRCRITICAL 15";
0041
0042 #define INIT_PRIORITY 2
0043 #define BLOCKER_PRIORITY 1
0044
0045 typedef struct {
0046 rtems_id secondary_task_id;
0047 rtems_id semaphore;
0048 Thread_Control *main_thread;
0049 } test_context;
0050
0051 static rtems_task Secondary_task( rtems_task_argument arg )
0052 {
0053 test_context *ctx;
0054 rtems_status_code sc;
0055
0056 ctx = (test_context *) arg;
0057
0058 while (1) {
0059 sc = rtems_semaphore_obtain( ctx->semaphore, RTEMS_DEFAULT_OPTIONS, 1 );
0060 T_quiet_rsc( sc, RTEMS_TIMEOUT );
0061 }
0062 }
0063
0064 static T_interrupt_test_state interrupt(void *arg)
0065 {
0066 test_context *ctx;
0067 Thread_Wait_flags flags;
0068 T_interrupt_test_state state;
0069
0070 ctx = arg;
0071 flags = _Thread_Wait_flags_get( ctx->main_thread );
0072
0073 if (
0074 flags == ( THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_INTEND_TO_BLOCK )
0075 ) {
0076 state = T_INTERRUPT_TEST_DONE;
0077 } else if (
0078 flags == ( THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_BLOCKED )
0079 ) {
0080 state = T_INTERRUPT_TEST_LATE;
0081 } else {
0082 state = T_INTERRUPT_TEST_EARLY;
0083 }
0084
0085 return state;
0086 }
0087
0088 static void prepare( void *arg )
0089 {
0090 test_context *ctx;
0091 rtems_status_code sc;
0092
0093 ctx = arg;
0094 sc = rtems_task_restart( ctx->secondary_task_id, (rtems_task_argument) ctx );
0095 T_quiet_rsc_success( sc );
0096 }
0097
0098 static void action( void *arg )
0099 {
0100 test_context *ctx;
0101 rtems_status_code sc;
0102
0103 ctx = arg;
0104 sc = rtems_semaphore_obtain( ctx->semaphore, RTEMS_DEFAULT_OPTIONS, 1 );
0105 T_quiet_rsc( sc, RTEMS_TIMEOUT );
0106 }
0107
0108 static const T_interrupt_test_config config = {
0109 .prepare = prepare,
0110 .action = action,
0111 .interrupt = interrupt,
0112 .max_iteration_count = 10000
0113 };
0114
0115 T_TEST_CASE( SemaphoreObtainBlockedInterrupt )
0116 {
0117 test_context ctx;
0118 rtems_status_code sc;
0119 T_interrupt_test_state state;
0120
0121 ctx.main_thread = _Thread_Get_executing();
0122
0123 sc = rtems_semaphore_create(
0124 rtems_build_name( 'S', 'M', '1', ' ' ),
0125 0,
0126 RTEMS_DEFAULT_ATTRIBUTES,
0127 RTEMS_NO_PRIORITY,
0128 &ctx.semaphore
0129 );
0130 T_assert_rsc_success( sc );
0131
0132 sc = rtems_task_create(
0133 rtems_build_name( 'B', 'L', 'C', 'K' ),
0134 BLOCKER_PRIORITY,
0135 RTEMS_MINIMUM_STACK_SIZE,
0136 RTEMS_NO_PREEMPT,
0137 RTEMS_DEFAULT_ATTRIBUTES,
0138 &ctx.secondary_task_id
0139 );
0140 T_assert_rsc_success( sc );
0141
0142 sc = rtems_task_start(
0143 ctx.secondary_task_id,
0144 Secondary_task,
0145 (rtems_task_argument) &ctx
0146 );
0147 T_assert_rsc_success( sc );
0148
0149 state = T_interrupt_test( &config, &ctx );
0150 T_eq_int( state, T_INTERRUPT_TEST_DONE );
0151
0152 sc = rtems_task_delete( ctx.secondary_task_id );
0153 T_rsc_success( sc );
0154
0155 sc = rtems_semaphore_delete( ctx.semaphore );
0156 T_rsc_success( sc );
0157 }
0158
0159 static rtems_task Init( rtems_task_argument argument )
0160 {
0161 rtems_test_run( argument, TEST_STATE );
0162 }
0163
0164
0165
0166 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0167 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0168
0169 #define CONFIGURE_MAXIMUM_TASKS 2
0170 #define CONFIGURE_MAXIMUM_SEMAPHORES 1
0171 #define CONFIGURE_MICROSECONDS_PER_TICK 1000
0172 #define CONFIGURE_INIT_TASK_PRIORITY INIT_PRIORITY
0173 #define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_PREEMPT
0174 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0175
0176 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0177
0178 #define CONFIGURE_INIT
0179 #include <rtems/confdefs.h>
0180
0181