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 <sched.h>
0034 
0035 #define CONFIGURE_INIT
0036 #include "system.h"
0037 #include <errno.h>
0038 #include "pritime.h"
0039 
0040 const char rtems_test_name[] = "PSX 9";
0041 
0042 static int get_current_prio( void )
0043 {
0044   rtems_status_code sc;
0045   rtems_task_priority prio;
0046   int max;
0047 
0048   sc = rtems_task_set_priority( RTEMS_SELF, RTEMS_CURRENT_PRIORITY, &prio );
0049   rtems_test_assert( sc == RTEMS_SUCCESSFUL );
0050 
0051   max = sched_get_priority_max( SCHED_FIFO );
0052 
0053   return max + 1 - (int) prio;
0054 }
0055 
0056 static void *mutex_lock_task(void *arg)
0057 {
0058   pthread_mutex_t *mtx;
0059   int              eno;
0060 
0061   mtx = arg;
0062 
0063   eno = pthread_mutex_lock( mtx );
0064   rtems_test_assert( eno == 0 );
0065 
0066   sched_yield();
0067 
0068   eno = pthread_mutex_unlock( mtx );
0069   rtems_test_assert( eno == 0 );
0070 
0071   return NULL;
0072 }
0073 
0074 static void test_destroy_locked_mutex(void)
0075 {
0076   pthread_mutex_t mtx;
0077   pthread_t       th;
0078   int             eno;
0079 
0080   eno = pthread_mutex_init( &mtx, NULL );
0081   rtems_test_assert( eno == 0 );
0082 
0083   eno = pthread_create( &th, NULL, mutex_lock_task, &mtx );
0084   rtems_test_assert( eno == 0 );
0085 
0086   sched_yield();
0087 
0088   eno = pthread_mutex_destroy( &mtx );
0089   rtems_test_assert( eno == EBUSY );
0090 
0091   sched_yield();
0092 
0093   eno = pthread_mutex_destroy( &mtx );
0094   rtems_test_assert( eno == 0 );
0095 
0096   eno = pthread_join( th, NULL );
0097   rtems_test_assert( eno == 0 );
0098 }
0099 
0100 void *POSIX_Init(
0101   void *argument
0102 )
0103 {
0104   int                  status;
0105   int                  passes;
0106   int                  schedpolicy;
0107   int                  priority;
0108   struct sched_param   schedparam;
0109   char                 buffer[ 80 ];
0110   pthread_mutexattr_t  attr;
0111   time_t               start;
0112   int                  ceiling_priority;
0113   int                  high_priority;
0114   int                  low_priority;
0115   rtems_id             scheduler_id;
0116   rtems_task_priority  rtems_priority;
0117   rtems_status_code    sc;
0118 
0119   if (argument != NULL ) {
0120     /* We end up here due to the rtems_task_restart() below */
0121 
0122     ceiling_priority = sched_get_priority_max( SCHED_SPORADIC );
0123     low_priority = ceiling_priority - 2;
0124     rtems_test_assert( get_current_prio() == low_priority );
0125 
0126     while ( get_current_prio() == low_priority ) {
0127       /* Be busy until sched_ss_repl_period elapses */
0128     }
0129 
0130     rtems_test_assert( get_current_prio() == 2 );
0131 
0132     TEST_END();
0133     rtems_test_exit( 0 );
0134   }
0135 
0136   TEST_BEGIN();
0137 
0138   ceiling_priority = sched_get_priority_max( SCHED_SPORADIC );
0139   high_priority = ceiling_priority - 1;
0140   low_priority = ceiling_priority - 2;
0141 
0142   test_destroy_locked_mutex();
0143 
0144   /* set the time of day, and print our buffer in multiple ways */
0145 
0146   set_time( TM_FRIDAY, TM_MAY, 24, 96, 11, 5, 0 );
0147 
0148   /* get id of this thread */
0149 
0150   Init_id = pthread_self();
0151   printf( "Init's ID is 0x%08" PRIxpthread_t "\n", Init_id );
0152 
0153   /* try to use this thread as a sporadic server */
0154 
0155   puts( "Init: pthread_getschedparam - SUCCESSFUL" );
0156   status = pthread_getschedparam( pthread_self(), &schedpolicy, &schedparam );
0157   rtems_test_assert( !status );
0158 
0159   priority = schedparam.sched_priority;
0160   sprintf( buffer, " - current priority = %d", priority );
0161   print_current_time( "Init: ", buffer );
0162 
0163   schedparam.sched_ss_repl_period.tv_sec = 2;
0164   schedparam.sched_ss_repl_period.tv_nsec = 0;
0165   schedparam.sched_ss_init_budget.tv_sec = 1;
0166   schedparam.sched_ss_init_budget.tv_nsec = 0;
0167 
0168   schedparam.sched_priority = high_priority;
0169   schedparam.sched_ss_low_priority = low_priority;
0170 
0171   puts( "Init: pthread_setschedparam - SUCCESSFUL (sporadic server)" );
0172   status = pthread_setschedparam( pthread_self(), SCHED_SPORADIC, &schedparam );
0173   rtems_test_assert( !status );
0174 
0175   sprintf( buffer, " - new priority = %d", get_current_prio() );
0176   print_current_time( "Init: ", buffer );
0177 
0178   /* go into a loop consuming CPU time to watch our priority change */
0179 
0180   for ( passes=0 ; passes <= 3 ; ) {
0181     int current_priority;
0182 
0183     current_priority = get_current_prio();
0184 
0185     if ( priority != current_priority ) {
0186       priority = current_priority;
0187       sprintf( buffer, " - new priority = %d", priority );
0188       print_current_time( "Init: ", buffer );
0189       passes++;
0190     }
0191   }
0192 
0193   /* now see if this works if we are holding a priority ceiling mutex */
0194 
0195   empty_line();
0196 
0197   status = pthread_getschedparam( pthread_self(), &schedpolicy, &schedparam );
0198   rtems_test_assert( !status );
0199 
0200   schedparam.sched_ss_repl_period.tv_sec = 0;
0201   schedparam.sched_ss_repl_period.tv_nsec = 500000000;  /* 1/2 second */
0202   schedparam.sched_ss_init_budget.tv_sec = 0;
0203   schedparam.sched_ss_init_budget.tv_nsec = 250000000;    /* 1/4 second */
0204 
0205   schedparam.sched_priority = high_priority;
0206   schedparam.sched_ss_low_priority = low_priority;
0207 
0208   puts( "Init: pthread_setschedparam - SUCCESSFUL (sporadic server)" );
0209   status = pthread_setschedparam( pthread_self(), SCHED_SPORADIC, &schedparam );
0210   rtems_test_assert( !status );
0211 
0212   puts( "Init: Initializing mutex attributes for priority ceiling" );
0213   status = pthread_mutexattr_init( &attr );
0214   rtems_test_assert( !status );
0215 
0216   status = pthread_mutexattr_setprotocol( &attr, PTHREAD_PRIO_PROTECT );
0217   rtems_test_assert( !status );
0218 
0219   status = pthread_mutexattr_setprioceiling( &attr, ceiling_priority );
0220   rtems_test_assert( !status );
0221 
0222   puts( "Init: Creating a mutex" );
0223   status = pthread_mutex_init( &Mutex_id, &attr );
0224   if ( status )
0225     printf( "status = %d\n", status );
0226   rtems_test_assert( !status );
0227 
0228   sprintf( buffer, " - new priority = %d", get_current_prio() );
0229   print_current_time( "Init: ", buffer );
0230 
0231   start = time( &start );
0232 
0233   puts( "Init: Go into low priority and lock/unlock ceiling mutex" );
0234 
0235   while ( get_current_prio() == low_priority ) {
0236     /* Be busy until sched_ss_repl_period elapses */
0237   }
0238 
0239   rtems_test_assert( get_current_prio() == high_priority );
0240   status = pthread_mutex_lock( &Mutex_id );
0241   if ( status )
0242     printf( "status = %d %s\n", status, strerror(status) );
0243   rtems_test_assert( !status );
0244   rtems_test_assert( get_current_prio() == ceiling_priority );
0245 
0246   status = pthread_mutex_unlock( &Mutex_id );
0247   if ( status )
0248     printf( "status = %d %s\n", status, strerror(status) );
0249   rtems_test_assert( !status );
0250   rtems_test_assert( get_current_prio() == high_priority );
0251 
0252   puts( "Init: Go into high priority and lock/unlock ceiling mutex" );
0253 
0254   while ( get_current_prio() == high_priority ) {
0255     /* Be busy until sched_ss_init_budget elapses */
0256   }
0257 
0258   rtems_test_assert( get_current_prio() == low_priority );
0259   status = pthread_mutex_lock( &Mutex_id );
0260   if ( status )
0261     printf( "status = %d %s\n", status, strerror(status) );
0262   rtems_test_assert( !status );
0263   rtems_test_assert( get_current_prio() == ceiling_priority );
0264 
0265   status = pthread_mutex_unlock( &Mutex_id );
0266   if ( status )
0267     printf( "status = %d\n", status );
0268   rtems_test_assert( !status );
0269   rtems_test_assert( get_current_prio() == low_priority );
0270 
0271   status = pthread_mutex_destroy( &Mutex_id );
0272   rtems_test_assert( status == 0 );
0273 
0274   puts( "Init: Go into low priority and change scheduler parameters" );
0275 
0276   while ( get_current_prio() == high_priority ) {
0277     /* Be busy until sched_ss_init_budget elapses */
0278   }
0279 
0280   rtems_test_assert( get_current_prio() == low_priority );
0281   schedparam.sched_priority = ceiling_priority;
0282   status = pthread_setschedparam( pthread_self(), SCHED_SPORADIC, &schedparam );
0283   rtems_test_assert( status == 0 );
0284   rtems_test_assert( get_current_prio() == ceiling_priority );
0285 
0286   puts( "Init: Go into low priority and set POSIX priority" );
0287 
0288   schedparam.sched_priority = high_priority;
0289   status = pthread_setschedparam( pthread_self(), SCHED_SPORADIC, &schedparam );
0290   rtems_test_assert( status == 0 );
0291   rtems_test_assert( get_current_prio() == high_priority );
0292 
0293   while ( get_current_prio() == high_priority ) {
0294     /* Be busy until sched_ss_init_budget elapses */
0295   }
0296 
0297   rtems_test_assert( get_current_prio() == low_priority );
0298   status = pthread_setschedprio( pthread_self(), ceiling_priority );
0299   rtems_test_assert( status == 0 );
0300   rtems_test_assert( get_current_prio() == low_priority );
0301 
0302   while ( get_current_prio() == low_priority ) {
0303     /* Be busy until sched_ss_repl_period elapses */
0304   }
0305 
0306   rtems_test_assert( get_current_prio() == ceiling_priority );
0307 
0308   puts( "Init: Go into low priority and set RTEMS priority" );
0309 
0310   sc = rtems_task_get_scheduler( RTEMS_SELF, &scheduler_id );
0311   rtems_test_assert( sc == RTEMS_SUCCESSFUL );
0312   sc = rtems_scheduler_map_priority_from_posix(
0313     scheduler_id,
0314     ceiling_priority,
0315     &rtems_priority
0316   );
0317   rtems_test_assert( sc == RTEMS_SUCCESSFUL );
0318 
0319   schedparam.sched_priority = high_priority;
0320   status = pthread_setschedparam( pthread_self(), SCHED_SPORADIC, &schedparam );
0321   rtems_test_assert( status == 0 );
0322   rtems_test_assert( get_current_prio() == high_priority );
0323 
0324   while ( get_current_prio() == high_priority ) {
0325     /* Be busy until sched_ss_init_budget elapses */
0326   }
0327 
0328   rtems_test_assert( get_current_prio() == low_priority );
0329   sc = rtems_task_set_priority( RTEMS_SELF, rtems_priority, &rtems_priority );
0330   rtems_test_assert( sc == RTEMS_SUCCESSFUL );
0331   rtems_test_assert( get_current_prio() == low_priority );
0332 
0333   while ( get_current_prio() == low_priority ) {
0334     /* Be busy until sched_ss_repl_period elapses */
0335   }
0336 
0337   rtems_test_assert( get_current_prio() == ceiling_priority );
0338 
0339   puts( "Init: Go into low priority and set scheduler" );
0340 
0341   sc = rtems_scheduler_ident_by_processor( 1, &scheduler_id );
0342   rtems_test_assert( sc == RTEMS_SUCCESSFUL );
0343 
0344   schedparam.sched_priority = high_priority;
0345   status = pthread_setschedparam( pthread_self(), SCHED_SPORADIC, &schedparam );
0346   rtems_test_assert( status == 0 );
0347   rtems_test_assert( get_current_prio() == high_priority );
0348 
0349   while ( get_current_prio() == high_priority ) {
0350     /* Be busy until sched_ss_init_budget elapses */
0351   }
0352 
0353   rtems_test_assert( get_current_prio() == low_priority );
0354   sc = rtems_task_set_scheduler( RTEMS_SELF, scheduler_id, 1 );
0355   rtems_test_assert( sc == RTEMS_RESOURCE_IN_USE );
0356   rtems_test_assert( get_current_prio() == low_priority );
0357 
0358   while ( get_current_prio() == low_priority ) {
0359     /* Be busy until sched_ss_repl_period elapses */
0360   }
0361 
0362   rtems_test_assert( get_current_prio() == high_priority );
0363 
0364   puts( "Init: Go into low priority and restart task" );
0365 
0366   schedparam.sched_priority = high_priority;
0367   status = pthread_setschedparam( pthread_self(), SCHED_SPORADIC, &schedparam );
0368   rtems_test_assert( status == 0 );
0369   rtems_test_assert( get_current_prio() == high_priority );
0370 
0371   while ( get_current_prio() == high_priority ) {
0372     /* Be busy until sched_ss_init_budget elapses */
0373   }
0374 
0375   rtems_test_assert( get_current_prio() == low_priority );
0376   (void) rtems_task_restart( RTEMS_SELF, 1 );
0377 
0378   return NULL; /* just so the compiler thinks we returned something */
0379 }