/* * COPYRIGHT (c) 1989-2012. * 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 #include #include #include #include #include const char rtems_test_name[] = "PSXSIGNAL 2"; /* forward declarations to avoid warnings */ void *POSIX_Init(void *argument); void *Test_Thread(void *arg); void Signal_handler(int signo); void Install_Signal_Handler(const char *task_name); volatile bool Signal_occurred; volatile pthread_t Signal_thread; static void block_all_signals(void) { int sc; sigset_t mask; sc = sigfillset( &mask ); rtems_test_assert( !sc ); sc = pthread_sigmask( SIG_BLOCK, &mask, NULL ); rtems_test_assert( !sc ); } void Signal_handler( int signo ) { Signal_occurred = true; Signal_thread = pthread_self(); } void Install_Signal_Handler( const char *task_name ) { int sc; sigset_t mask; sc = sigemptyset( &mask ); rtems_test_assert( !sc ); sc = sigaddset( &mask, SIGUSR1 ); rtems_test_assert( !sc ); printf( "%s - Unblock SIGUSR1\n", task_name ); sc = pthread_sigmask( SIG_UNBLOCK, &mask, NULL ); rtems_test_assert( !sc ); } /* Tasks and actions, created in this order, all interested in SIGUSR1 - 20 - interested, suspend? - 18 - interested, suspend? - 16 - interested, spins - 14 - interested, spins - 12 - interested, sleeps - 10 - interested, suspends - 8 - interested, sleeps Order is critical because the algorithm works by thread index */ typedef enum { SUSPEND, SPIN, SLEEP } Action_t; const char *Actions[] = { "Suspends self", "Spins", "Sleeps" }; typedef struct { int priority; Action_t action; const char *name; } Test_t; Test_t Threads[] = { { 8, SUSPEND, "P8" }, /* base priority */ { 7, SUSPEND, "P7" }, /* lower priority -- no change */ { 12, SUSPEND, "P12" }, /* higher priority, blocked */ { 12, SUSPEND, "P12" }, /* equal priority, blocked */ { 12, SLEEP, "P12" }, /* equal priority, interruptible */ { 12, SLEEP, "P12" }, /* equal priority, interruptible */ { 12, SPIN, "P12" }, /* equal priority, ready */ { 12, SPIN, "P12" }, /* equal priority, ready -- no change */ { -1, 0, "" }, }; void *Test_Thread(void *arg) { Test_t *test = (Test_t *)arg; Install_Signal_Handler( test->name ); printf( "%s - %s\n", test->name, Actions[test->action] ); switch ( test->action ) { case SUSPEND: (void) rtems_task_suspend( RTEMS_SELF ); break; case SPIN: while (1) ; break; case SLEEP: sleep( 30 ); break; } printf( "%s - exiting\n", test->name ); return NULL; } void *POSIX_Init( void *argument ) { int i; int sc; pthread_t id; pthread_attr_t attr; struct sched_param param; Test_t *test; struct sigaction act; struct timespec delay_request; TEST_BEGIN(); Signal_occurred = false; block_all_signals(); act.sa_handler = Signal_handler; act.sa_flags = 0; sigaction( SIGUSR1, &act, NULL ); puts( "Init - Raise my priority" ); sc = pthread_attr_init( &attr ); rtems_test_assert( !sc ); param.sched_priority = 30; sc = pthread_setschedparam( pthread_self(), SCHED_RR, ¶m ); rtems_test_assert( !sc ); for ( i=0, test=Threads ; test->priority != -1 ; i++, test++ ) { printf( "Init - Create thread %d, priority=%d\n", i, test->priority ); sc = pthread_attr_init( &attr ); rtems_test_assert( !sc ); sc = pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED ); rtems_test_assert( !sc ); sc = pthread_attr_setschedpolicy( &attr, SCHED_RR ); rtems_test_assert( !sc ); param.sched_priority = test->priority; sc = pthread_attr_setschedparam( &attr, ¶m ); rtems_test_assert( !sc ); sc = pthread_create( &id, &attr, Test_Thread, test ); rtems_test_assert( !sc ); puts( "Init - sleep - let thread settle - OK" ); delay_request.tv_sec = 0; delay_request.tv_nsec = 50000000; sc = nanosleep( &delay_request, NULL ); rtems_test_assert( !sc ); } puts( "Init - sending SIGUSR1" ); sc = kill( getpid(), SIGUSR1 ); rtems_test_assert( !sc ); /* we are just scheduling the signal, not delivering it */ rtems_test_assert( Signal_occurred == false ); TEST_END(); rtems_test_exit(0); return NULL; /* just so the compiler thinks we returned something */ } /* configuration information */ #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER #define CONFIGURE_MICROSECONDS_PER_TICK 1000 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION #define CONFIGURE_MAXIMUM_POSIX_THREADS 9 #define CONFIGURE_POSIX_INIT_THREAD_TABLE #define CONFIGURE_INIT #include