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 #include <rtems/score/threadimpl.h>
0040 #include <rtems/score/watchdogimpl.h>
0041
0042 const char rtems_test_name[] = "SPINTRCRITICAL 9";
0043
0044 typedef struct {
0045 Thread_Control *thread;
0046 rtems_id semaphore;
0047 volatile bool early;
0048 } test_context;
0049
0050 static bool is_interrupt_timeout( test_context *ctx )
0051 {
0052 Thread_Wait_flags flags = _Thread_Wait_flags_get( ctx->thread );
0053
0054 return flags == THREAD_WAIT_STATE_READY;
0055 }
0056
0057 static T_interrupt_test_state interrupt( void *arg )
0058 {
0059 test_context *ctx;
0060 Per_CPU_Control *cpu_self;
0061 Watchdog_Header *header;
0062 Watchdog_Control *watchdog;
0063 T_interrupt_test_state state;
0064
0065 ctx = arg;
0066 cpu_self = _Per_CPU_Get();
0067 header = &cpu_self->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ];
0068 watchdog = (Watchdog_Control *) header->first;
0069
0070 if (
0071 watchdog != NULL
0072 && watchdog->expire == cpu_self->Watchdog.ticks
0073 && watchdog->routine == _Thread_Timeout
0074 ) {
0075 ISR_Level level;
0076
0077 _ISR_Local_disable( level );
0078 _Watchdog_Per_CPU_remove( watchdog, cpu_self, header );
0079 _ISR_Local_enable( level );
0080
0081 ( *watchdog->routine )( watchdog );
0082
0083 if ( is_interrupt_timeout( ctx ) ) {
0084 state = T_INTERRUPT_TEST_DONE;
0085 } else {
0086 state = T_INTERRUPT_TEST_LATE;
0087 }
0088 } else {
0089 if ( ctx->early ) {
0090 state = T_INTERRUPT_TEST_EARLY;
0091 } else {
0092 state = T_INTERRUPT_TEST_LATE;
0093 }
0094 }
0095
0096 return state;
0097 }
0098
0099 static void prepare( void *arg )
0100 {
0101 test_context *ctx;
0102 rtems_status_code sc;
0103
0104 ctx = arg;
0105 ctx->early = true;
0106 sc = rtems_semaphore_obtain( ctx->semaphore, RTEMS_NO_WAIT, 0 );
0107 T_quiet_true( sc == RTEMS_SUCCESSFUL || sc == RTEMS_UNSATISFIED );
0108 }
0109
0110 static void action( void *arg )
0111 {
0112 test_context *ctx;
0113 rtems_status_code sc;
0114
0115 ctx = arg;
0116 ctx->early = false;
0117 sc = rtems_semaphore_obtain( ctx->semaphore, RTEMS_DEFAULT_OPTIONS, 1 );
0118 T_quiet_rsc( sc, RTEMS_TIMEOUT );
0119 }
0120
0121 static const T_interrupt_test_config config = {
0122 .prepare = prepare,
0123 .action = action,
0124 .interrupt = interrupt,
0125 .max_iteration_count = 10000
0126 };
0127
0128 T_TEST_CASE( SemaphoreObtainInterrupt )
0129 {
0130 test_context ctx;
0131 rtems_status_code sc;
0132 T_interrupt_test_state state;
0133
0134 ctx.thread = _Thread_Get_executing();
0135
0136 sc = rtems_semaphore_create(
0137 rtems_build_name( 'S', 'M', '1', ' ' ),
0138 0,
0139 RTEMS_DEFAULT_ATTRIBUTES,
0140 RTEMS_NO_PRIORITY,
0141 &ctx.semaphore
0142 );
0143 T_assert_rsc_success( sc );
0144
0145 state = T_interrupt_test( &config, &ctx );
0146 T_eq_int( state, T_INTERRUPT_TEST_DONE );
0147
0148 sc = rtems_semaphore_delete( ctx.semaphore );
0149 T_rsc_success( sc );
0150 }
0151
0152 static rtems_task Init( rtems_task_argument argument )
0153 {
0154 rtems_test_run( argument, TEST_STATE );
0155 }
0156
0157
0158
0159 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0160 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0161
0162 #define CONFIGURE_MAXIMUM_TASKS 1
0163 #define CONFIGURE_MAXIMUM_SEMAPHORES 1
0164 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0165
0166 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0167 #define CONFIGURE_MICROSECONDS_PER_TICK 1000
0168
0169 #define CONFIGURE_INIT
0170 #include <rtems/confdefs.h>
0171
0172