summaryrefslogblamecommitdiffstats
path: root/testsuites/psxtests/psxsignal02/init.c
blob: c7a9432415f36d6153e3e55341be5ca6c3c1e642 (plain) (tree)
1
2
3
4
5
6
7
8
9
  
                            



                                                           
                                         

   


                    






                    

                                             





                                                   


                                   











                                                 













                                   

                            
                           

                                   
                           


                                                   
                           


























                                                                   
 























                                                                    
 



























                                                           
                          
                                    
 
               


                          

                      





                                     
                           


                                                                 
                           



                                                                          
                             

                                                                       
                             

                                                        
                             


                                                     
                             

                                                         
                             

                                                    


                                           
                             



                                   
                           

                                                            
                                                
 
             






                                                                      
                                                         


                                                   

                                                                 





                                                
/*
 *  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 <pmacros.h>
#include <signal.h>
#include <errno.h>
#include <pthread.h>
#include <sched.h>

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, &param );
  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, &param );
    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 <rtems/confdefs.h>