diff options
Diffstat (limited to 'testsuites/sptests/spintrcritical21/init.c')
-rw-r--r-- | testsuites/sptests/spintrcritical21/init.c | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/testsuites/sptests/spintrcritical21/init.c b/testsuites/sptests/spintrcritical21/init.c new file mode 100644 index 0000000000..8b1ddcfc37 --- /dev/null +++ b/testsuites/sptests/spintrcritical21/init.c @@ -0,0 +1,170 @@ +/* + * 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 <intrcritical.h> + +#include <rtems/rtems/eventimpl.h> + +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 ); +} |