/* * Classic API Signal to Task from ISR * * COPYRIGHT (c) 1989-2011. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.org/license/LICENSE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define CONFIGURE_INIT #include "system.h" #include #include const char rtems_test_name[] = "SPINTRCRITICAL 21"; /* * ERROR CHECKING NOTE: * * We are either at dispatch disable level 1 or 2. Either way, it is * safer not to check the dispatch level explicitly so we are using * fatal_directive_check_status_only() not directive_failed(). */ static volatile bool case_hit; static rtems_id main_task; static rtems_id other_task; static rtems_timer_service_routine test_event_from_isr( rtems_id timer, void *arg ) { rtems_status_code status; if ( _Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) { /* * This event send hits the critical section but sends to * another task so doesn't impact this critical section. */ status = rtems_event_send( other_task, 0x02 ); fatal_directive_check_status_only( status, RTEMS_SUCCESSFUL, "event send" ); /* * This event send hits the main task but doesn't satisfy * it's blocking condition so it will still block */ status = rtems_event_send( main_task, 0x02 ); fatal_directive_check_status_only( status, RTEMS_SUCCESSFUL, "event send" ); case_hit = true; } status = rtems_event_send( main_task, 0x01 ); fatal_directive_check_status_only( status, RTEMS_SUCCESSFUL, "event send" ); } static bool test_body_event_from_isr( void *arg ) { rtems_status_code status; rtems_event_set out; (void) arg; status = rtems_event_receive( 0x01, RTEMS_DEFAULT_OPTIONS, 0, &out ); rtems_test_assert( status == RTEMS_SUCCESSFUL ); return case_hit; } static rtems_timer_service_routine test_event_with_timeout_from_isr( rtems_id timer, void *arg ) { rtems_status_code status; if ( _Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) { /* * We want to catch the task while it is blocking. Otherwise * just send and make it happy. */ case_hit = true; } status = rtems_event_send( main_task, 0x01 ); fatal_directive_check_status_only( status, RTEMS_SUCCESSFUL, "event send" ); } static bool test_body_event_with_timeout_from_isr( void *arg ) { rtems_status_code status; rtems_event_set out; (void) arg; status = rtems_event_receive( 0x01, RTEMS_DEFAULT_OPTIONS, 1, &out ); rtems_test_assert( status == RTEMS_SUCCESSFUL || status == RTEMS_TIMEOUT ); return case_hit; } rtems_task Init( rtems_task_argument argument ) { rtems_status_code status; TEST_BEGIN(); main_task = rtems_task_self(); status = rtems_task_create( 0xa5a5a5a5, 1, RTEMS_MINIMUM_STACK_SIZE, RTEMS_DEFAULT_MODES, RTEMS_DEFAULT_ATTRIBUTES, &other_task ); directive_failed( status, "rtems_task_create" ); /* * Test Event send successful from ISR -- receive is forever */ case_hit = false; interrupt_critical_section_test( test_body_event_from_isr, NULL, test_event_from_isr ); printf( "Event sent from ISR hitting synchronization point has %soccurred\n", case_hit ? "" : "NOT " ); rtems_test_assert( case_hit ); /* * Test Event send successful from ISR -- receive has timeout */ case_hit = false; interrupt_critical_section_test( test_body_event_with_timeout_from_isr, NULL, test_event_with_timeout_from_isr ); printf( "Event sent from ISR (with timeout) hitting synchronization " "point has %soccurred\n", case_hit ? "" : "NOT " ); rtems_test_assert( case_hit ); TEST_END(); rtems_test_exit( 0 ); }