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

                                                           
                                         

   



                    
                     
                  



                     
 
                    
 
                                        
 
























































                                                                      
                                              
 











                                               


                                      

 
                                         
 
                          

                             
                             
                                 
                        
 
               
 

                       





                                                                  
                                                                    
 



                                                 
                               
 
                                                                         
                               


                                                                      
                                                                   
                                        




                                                 
                               


                                                                          
                               
 



                                              
 
                                  
                                         

                                                            
                               
 
                                                                         
                               
 
                                                               
                                                                   
                                        
 
                                           
 



                                                                     
 
                                           
                                        

                                                            
                               
 
                                                                          
                                                                   
                                        


                                            



                                                                     
 

                                                 
 
                                                            
                               
 
                                              






                                                                  
                               
 

                                        
 




                                                                            
 
             
                       


                                                                      












                                                                 
/*
 *  COPYRIGHT (c) 1989-2009.
 *  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 <sys/time.h>
#include <errno.h>
#include <inttypes.h>
#include <sched.h>
#include <stdint.h>
#include <unistd.h>

#include <pmacros.h>

const char rtems_test_name[] = "PSX 12";

#define SS_REPL_PERIOD_US 200000

#define SS_INIT_BUDGET_US 100000

#define SS_PRIO_LOW 1

#define SS_PRIO_HIGH 2

#define SS_SAMPLE_PERIODS 3

typedef struct {
  uint64_t start;
  struct {
    uint64_t high;
    uint64_t low;
  } samples[ SS_SAMPLE_PERIODS ];
} test_context;

static test_context test_instance;

static void wait_for_prio( int prio )
{
  int                status;
  int                policy;
  struct sched_param param;

  do {
    status = pthread_getschedparam( pthread_self(), &policy, &param );
    rtems_test_assert( status == 0 );
  } while ( prio != param.sched_priority );
}

static uint64_t timeval_to_us( const struct timeval *tv )
{
  uint64_t t;

  t = tv->tv_sec;
  t *= 1000000;
  t += tv->tv_usec;

  return t;
}

static uint64_t now( void )
{
  struct timeval now;

  gettimeofday( &now, NULL );

  return timeval_to_us( &now );
}

static uint64_t delta( test_context *ctx )
{
  return now() - ctx->start;
}

static void *sporadic_server( void *argument )
{
  test_context *ctx;
  size_t        i;

  ctx = argument;

  for ( i = 0 ; i < SS_SAMPLE_PERIODS ; ++i ) {
    wait_for_prio( SS_PRIO_LOW );
    ctx->samples[ i ].high = delta( ctx );
    wait_for_prio( SS_PRIO_HIGH );
    ctx->samples[ i ].low = delta( ctx );
  }

  puts( "Sporadic Server: exitting" );

  return NULL;
}

static void *POSIX_Init( void *argument )
{
  test_context       *ctx;
  int                 status;
  pthread_attr_t      attr;
  pthread_t           thread;
  struct sched_param  schedparam;
  size_t              i;

  TEST_BEGIN();

  ctx = &test_instance;

  /* set the time of day, and print our buffer in multiple ways */

  set_time( TM_FRIDAY, TM_MAY, 24, 96, 11, 5, 0 );

  /* get id of this thread */

  printf( "Init's ID is 0x%08" PRIxpthread_t "\n", pthread_self() );

  /* invalid scheduling policy error */

  puts( "Init: pthread_attr_init - SUCCESSFUL" );
  status = pthread_attr_init( &attr );
  rtems_test_assert( !status );

  status = pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
  rtems_test_assert( !status );
  attr.schedpolicy = -1;

  puts( "Init: pthread_create - EINVAL (invalid scheduling policy)" );
  status = pthread_create( &thread, &attr, sporadic_server, NULL );
  rtems_test_assert( status == EINVAL );

  /* replenish period < budget error */

  puts( "Init: pthread_attr_init - SUCCESSFUL" );
  status = pthread_attr_init( &attr );
  rtems_test_assert( !status );

  puts( "Init: set scheduling parameter attributes for sporadic server" );
  status = pthread_attr_setschedpolicy( &attr, SCHED_SPORADIC );
  rtems_test_assert( !status );

  schedparam.sched_ss_repl_period.tv_sec = 1;
  schedparam.sched_ss_repl_period.tv_nsec = 0;
  schedparam.sched_ss_init_budget.tv_sec = 2;
  schedparam.sched_ss_init_budget.tv_nsec = 0;

  schedparam.sched_priority = 200;
  schedparam.sched_ss_low_priority = 100;

  status = pthread_attr_setschedparam( &attr, &schedparam );
  rtems_test_assert( !status );

  status = pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
  rtems_test_assert( !status );

  puts( "Init: pthread_create - EINVAL (replenish < budget)" );
  status = pthread_create( &thread, &attr, sporadic_server, NULL );
  rtems_test_assert( status == EINVAL );

  /* invalid sched_ss_low_priority error */

  schedparam.sched_ss_repl_period.tv_sec = 0;
  schedparam.sched_ss_repl_period.tv_nsec = SS_REPL_PERIOD_US * 1000;
  schedparam.sched_ss_init_budget.tv_sec = 0;
  schedparam.sched_ss_init_budget.tv_nsec = SS_INIT_BUDGET_US * 1000;

  schedparam.sched_priority = SS_PRIO_HIGH;
  schedparam.sched_ss_low_priority = -1;

  status = pthread_attr_setschedparam( &attr, &schedparam );
  rtems_test_assert( !status );

  puts( "Init: pthread_create - EINVAL (invalid sched_ss_low_priority)" );
  status = pthread_create( &thread, &attr, sporadic_server, NULL );
  rtems_test_assert( status == EINVAL );

  /* create a thread as a sporadic server */

  schedparam.sched_ss_repl_period.tv_sec = 0;
  schedparam.sched_ss_repl_period.tv_nsec = SS_REPL_PERIOD_US * 1000;
  schedparam.sched_ss_init_budget.tv_sec = 0;
  schedparam.sched_ss_init_budget.tv_nsec = SS_INIT_BUDGET_US * 1000;

  schedparam.sched_priority = SS_PRIO_HIGH;
  schedparam.sched_ss_low_priority = SS_PRIO_LOW;

  status = pthread_attr_setschedparam( &attr, &schedparam );
  rtems_test_assert( !status );

  puts( "Init: pthread_create - SUCCESSFUL" );

  /* Align with clock tick */
  usleep( 1 );

  ctx->start = now();

  status = pthread_create( &thread, &attr, sporadic_server, ctx );
  rtems_test_assert( !status );

  status = pthread_join( thread, NULL );
  rtems_test_assert( !status );

  for ( i = 0 ; i < SS_SAMPLE_PERIODS ; ++i ) {
    printf( "[%zu] H %6" PRIu64 "us\n", i, ctx->samples[ i ].high );
    printf( "[%zu] L %6" PRIu64 "us\n", i, ctx->samples[ i ].low );
    rtems_test_assert( ctx->samples[ i ].low / SS_REPL_PERIOD_US == i + 1 );
  }

  TEST_END();
  rtems_test_exit( 0 );

  return NULL; /* just so the compiler thinks we returned something */
}

#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER

#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION

#define CONFIGURE_MAXIMUM_POSIX_THREADS 2

#define CONFIGURE_POSIX_INIT_THREAD_TABLE

#define CONFIGURE_INIT

#include <rtems/confdefs.h>