Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:47

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  *  Copyright (C) 2020 embedded brains GmbH & Co. KG
0005  *
0006  *  COPYRIGHT (c) 1989-2012.
0007  *  On-Line Applications Research Corporation (OAR).
0008  *
0009  * Redistribution and use in source and binary forms, with or without
0010  * modification, are permitted provided that the following conditions
0011  * are met:
0012  * 1. Redistributions of source code must retain the above copyright
0013  *    notice, this list of conditions and the following disclaimer.
0014  * 2. Redistributions in binary form must reproduce the above copyright
0015  *    notice, this list of conditions and the following disclaimer in the
0016  *    documentation and/or other materials provided with the distribution.
0017  *
0018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0019  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0020  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0021  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0022  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0023  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0024  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0025  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0026  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0027  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0028  * POSSIBILITY OF SUCH DAMAGE.
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 /* configuration information */
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 /* global variables */