File indexing completed on 2025-05-11 08:24:36
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #ifdef HAVE_CONFIG_H
0030 #include "config.h"
0031 #endif
0032
0033 #include <sys/time.h>
0034 #include <errno.h>
0035 #include <inttypes.h>
0036 #include <sched.h>
0037 #include <stdint.h>
0038 #include <unistd.h>
0039
0040 #include <pmacros.h>
0041
0042 const char rtems_test_name[] = "PSX 12";
0043
0044 #define SS_REPL_PERIOD_NS 200000000
0045
0046 #define SS_INIT_BUDGET_NS 100000000
0047
0048 #define SS_REPL_PERIOD_MS ( SS_REPL_PERIOD_NS / 1000000 )
0049
0050 #define SS_PRIO_LOW 1
0051
0052 #define SS_PRIO_HIGH 2
0053
0054 #define SS_SAMPLE_PERIODS 3
0055
0056 typedef struct {
0057 uint64_t start;
0058 struct {
0059 uint32_t high;
0060 uint32_t low;
0061 } samples[ SS_SAMPLE_PERIODS ];
0062 } test_context;
0063
0064 static test_context test_instance;
0065
0066 static int get_current_prio( pthread_t thread )
0067 {
0068 rtems_status_code sc;
0069 rtems_task_priority prio;
0070 int max;
0071
0072 sc = rtems_task_set_priority( thread, RTEMS_CURRENT_PRIORITY, &prio );
0073 rtems_test_assert( sc == RTEMS_SUCCESSFUL );
0074
0075 max = sched_get_priority_max( SCHED_FIFO );
0076
0077 return max + 1 - (int) prio;
0078 }
0079
0080 static void wait_for_prio( int prio )
0081 {
0082 while ( prio != get_current_prio( pthread_self() ) ) {
0083
0084 }
0085 }
0086
0087 static uint64_t timeval_to_us( const struct timeval *tv )
0088 {
0089 uint64_t t;
0090
0091 t = tv->tv_sec;
0092 t *= 1000000;
0093 t += tv->tv_usec;
0094
0095 return t;
0096 }
0097
0098 static uint64_t now( void )
0099 {
0100 struct timeval now;
0101
0102 gettimeofday( &now, NULL );
0103
0104 return timeval_to_us( &now );
0105 }
0106
0107 static uint32_t delta_in_ms( test_context *ctx )
0108 {
0109 uint32_t d;
0110
0111 d = (uint32_t) ( now() - ctx->start );
0112 return ( d + 499 ) / 1000;
0113 }
0114
0115 static void *sporadic_server( void *argument )
0116 {
0117 test_context *ctx;
0118 size_t i;
0119
0120 ctx = argument;
0121
0122 for ( i = 0 ; i < SS_SAMPLE_PERIODS ; ++i ) {
0123 wait_for_prio( SS_PRIO_LOW );
0124 ctx->samples[ i ].high = delta_in_ms( ctx );
0125 wait_for_prio( SS_PRIO_HIGH );
0126 ctx->samples[ i ].low = delta_in_ms( ctx );
0127 }
0128
0129 puts( "Sporadic Server: exitting" );
0130
0131 return NULL;
0132 }
0133
0134 static void *POSIX_Init( void *argument )
0135 {
0136 test_context *ctx;
0137 int status;
0138 pthread_attr_t attr;
0139 pthread_t thread;
0140 struct sched_param schedparam;
0141 size_t i;
0142
0143 TEST_BEGIN();
0144
0145 ctx = &test_instance;
0146
0147
0148
0149 set_time( TM_FRIDAY, TM_MAY, 24, 96, 11, 5, 0 );
0150
0151
0152
0153 printf( "Init's ID is 0x%08" PRIxpthread_t "\n", pthread_self() );
0154
0155
0156
0157 puts( "Init: pthread_attr_init - SUCCESSFUL" );
0158 status = pthread_attr_init( &attr );
0159 rtems_test_assert( !status );
0160
0161 status = pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
0162 rtems_test_assert( !status );
0163 attr.schedpolicy = -1;
0164
0165 puts( "Init: pthread_create - EINVAL (invalid scheduling policy)" );
0166 status = pthread_create( &thread, &attr, sporadic_server, NULL );
0167 rtems_test_assert( status == EINVAL );
0168
0169
0170
0171 puts( "Init: pthread_attr_init - SUCCESSFUL" );
0172 status = pthread_attr_init( &attr );
0173 rtems_test_assert( !status );
0174
0175 puts( "Init: set scheduling parameter attributes for sporadic server" );
0176 status = pthread_attr_setschedpolicy( &attr, SCHED_SPORADIC );
0177 rtems_test_assert( !status );
0178
0179 schedparam.sched_ss_repl_period.tv_sec = 1;
0180 schedparam.sched_ss_repl_period.tv_nsec = 0;
0181 schedparam.sched_ss_init_budget.tv_sec = 2;
0182 schedparam.sched_ss_init_budget.tv_nsec = 0;
0183
0184 schedparam.sched_priority = 200;
0185 schedparam.sched_ss_low_priority = 100;
0186
0187 status = pthread_attr_setschedparam( &attr, &schedparam );
0188 rtems_test_assert( !status );
0189
0190 status = pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
0191 rtems_test_assert( !status );
0192
0193 puts( "Init: pthread_create - EINVAL (replenish < budget)" );
0194 status = pthread_create( &thread, &attr, sporadic_server, NULL );
0195 rtems_test_assert( status == EINVAL );
0196
0197
0198
0199 schedparam.sched_ss_repl_period.tv_sec = 0;
0200 schedparam.sched_ss_repl_period.tv_nsec = SS_REPL_PERIOD_NS;
0201 schedparam.sched_ss_init_budget.tv_sec = 0;
0202 schedparam.sched_ss_init_budget.tv_nsec = SS_INIT_BUDGET_NS;
0203
0204 schedparam.sched_priority = SS_PRIO_HIGH;
0205 schedparam.sched_ss_low_priority = -1;
0206
0207 status = pthread_attr_setschedparam( &attr, &schedparam );
0208 rtems_test_assert( !status );
0209
0210 puts( "Init: pthread_create - EINVAL (invalid sched_ss_low_priority)" );
0211 status = pthread_create( &thread, &attr, sporadic_server, NULL );
0212 rtems_test_assert( status == EINVAL );
0213
0214
0215
0216 schedparam.sched_ss_repl_period.tv_sec = 0;
0217 schedparam.sched_ss_repl_period.tv_nsec = SS_REPL_PERIOD_NS;
0218 schedparam.sched_ss_init_budget.tv_sec = 0;
0219 schedparam.sched_ss_init_budget.tv_nsec = SS_INIT_BUDGET_NS;
0220
0221 schedparam.sched_priority = SS_PRIO_HIGH;
0222 schedparam.sched_ss_low_priority = SS_PRIO_LOW;
0223
0224 status = pthread_attr_setschedparam( &attr, &schedparam );
0225 rtems_test_assert( !status );
0226
0227 puts( "Init: pthread_create - SUCCESSFUL" );
0228
0229 pthread_setschedprio( pthread_self(), SS_PRIO_LOW );
0230
0231
0232 sleep( 1 );
0233
0234 ctx->start = now();
0235
0236 status = pthread_create( &thread, &attr, sporadic_server, ctx );
0237 rtems_test_assert( !status );
0238
0239 status = pthread_join( thread, NULL );
0240 rtems_test_assert( !status );
0241
0242 for ( i = 0 ; i < SS_SAMPLE_PERIODS ; ++i ) {
0243 printf( "[%zu] H %3" PRIu32 "ms\n", i, ctx->samples[ i ].high );
0244 printf( "[%zu] L %3" PRIu32 "ms\n", i, ctx->samples[ i ].low );
0245 rtems_test_assert( ctx->samples[ i ].low / SS_REPL_PERIOD_MS == i + 1 );
0246 }
0247
0248 TEST_END();
0249 rtems_test_exit( 0 );
0250
0251 return NULL;
0252 }
0253
0254 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0255 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0256
0257 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0258
0259 #define CONFIGURE_MAXIMUM_POSIX_THREADS 2
0260
0261 #define CONFIGURE_POSIX_INIT_THREAD_TABLE
0262
0263 #define CONFIGURE_INIT
0264
0265 #include <rtems/confdefs.h>