Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:36

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  *  COPYRIGHT (c) 1989-2009.
0005  *  On-Line Applications Research Corporation (OAR).
0006  *
0007  * Redistribution and use in source and binary forms, with or without
0008  * modification, are permitted provided that the following conditions
0009  * are met:
0010  * 1. Redistributions of source code must retain the above copyright
0011  *    notice, this list of conditions and the following disclaimer.
0012  * 2. Redistributions in binary form must reproduce the above copyright
0013  *    notice, this list of conditions and the following disclaimer in the
0014  *    documentation and/or other materials provided with the distribution.
0015  *
0016  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0017  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0018  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0019  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0020  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0021  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0022  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0023  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0024  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0025  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0026  * POSSIBILITY OF SUCH DAMAGE.
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     /* Wait */
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   /* set the time of day, and print our buffer in multiple ways */
0148 
0149   set_time( TM_FRIDAY, TM_MAY, 24, 96, 11, 5, 0 );
0150 
0151   /* get id of this thread */
0152 
0153   printf( "Init's ID is 0x%08" PRIxpthread_t "\n", pthread_self() );
0154 
0155   /* invalid scheduling policy error */
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   /* replenish period < budget error */
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   /* invalid sched_ss_low_priority error */
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   /* create a thread as a sporadic server */
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   /* Align with clock tick */
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; /* just so the compiler thinks we returned something */
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>