Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  *  COPYRIGHT (c) 1989-2012.
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 <pmacros.h>
0034 #include <signal.h>
0035 #include <errno.h>
0036 #include <pthread.h>
0037 #include <sched.h>
0038 
0039 const char rtems_test_name[] = "PSXSIGNAL 2";
0040 
0041 /* forward declarations to avoid warnings */
0042 void *POSIX_Init(void *argument);
0043 void *Test_Thread(void *arg);
0044 void Signal_handler(int signo);
0045 void Install_Signal_Handler(const char *task_name);
0046 
0047 volatile bool      Signal_occurred;
0048 volatile pthread_t Signal_thread;
0049 
0050 static void block_all_signals(void)
0051 {
0052   int               sc;
0053   sigset_t          mask;
0054 
0055   sc = sigfillset( &mask );
0056   rtems_test_assert( !sc );
0057 
0058   sc = pthread_sigmask( SIG_BLOCK, &mask, NULL );
0059   rtems_test_assert( !sc );
0060 }
0061 
0062 void Signal_handler(
0063   int signo
0064 )
0065 {
0066   Signal_occurred = true;
0067   Signal_thread   = pthread_self();
0068 }
0069 
0070 void Install_Signal_Handler(
0071   const char *task_name
0072 )
0073 {
0074   int               sc;
0075   sigset_t          mask;
0076 
0077   sc = sigemptyset( &mask );
0078   rtems_test_assert( !sc );
0079 
0080   sc = sigaddset( &mask, SIGUSR1 );
0081   rtems_test_assert( !sc );
0082 
0083   printf( "%s - Unblock SIGUSR1\n", task_name );
0084   sc = pthread_sigmask( SIG_UNBLOCK, &mask, NULL );
0085   rtems_test_assert( !sc );
0086 }
0087 
0088 /*
0089 
0090 Tasks and actions, created in this order, all interested in SIGUSR1
0091   - 20     - interested, suspend?
0092   - 18     - interested, suspend?
0093   - 16     - interested, spins
0094   - 14     - interested, spins
0095   - 12     - interested, sleeps
0096   - 10     - interested, suspends
0097   - 8      - interested, sleeps
0098 
0099 Order is critical because the algorithm works by thread index
0100 */
0101 
0102 typedef enum {
0103   SUSPEND,
0104   SPIN,
0105   SLEEP
0106 } Action_t;
0107 
0108 const char *Actions[] = {
0109   "Suspends self",
0110   "Spins",
0111   "Sleeps"
0112 };
0113 
0114 
0115 typedef struct {
0116   int         priority;
0117   Action_t    action;
0118   const char *name;
0119 } Test_t;
0120 
0121 Test_t Threads[] = {
0122   {  8, SUSPEND,  "P8"  },  /* base priority */
0123   {  7, SUSPEND,  "P7"  },  /* lower priority -- no change */
0124   { 12, SUSPEND,  "P12" },  /* higher priority, blocked */
0125   { 12, SUSPEND,  "P12" },  /* equal priority, blocked */
0126   { 12, SLEEP,    "P12" },  /* equal priority, interruptible */
0127   { 12, SLEEP,    "P12" },  /* equal priority, interruptible */
0128   { 12, SPIN,     "P12" },  /* equal priority, ready */
0129   { 12, SPIN,     "P12" },  /* equal priority, ready -- no change */
0130   { -1, 0,        ""    },
0131 };
0132 
0133 void *Test_Thread(void *arg)
0134 {
0135   Test_t *test = (Test_t *)arg;
0136 
0137   Install_Signal_Handler( test->name );
0138 
0139   printf( "%s - %s\n", test->name, Actions[test->action] );
0140   switch ( test->action ) {
0141     case SUSPEND:
0142       (void) rtems_task_suspend( RTEMS_SELF );
0143       break;
0144     case SPIN:
0145       while (1) ;
0146       break;
0147     case SLEEP:
0148       sleep( 30 );
0149       break;
0150   }
0151 
0152   printf( "%s - exiting\n", test->name );
0153   return NULL;
0154 
0155 }
0156 
0157 void *POSIX_Init(
0158   void *argument
0159 )
0160 {
0161   int                 i;
0162   int                 sc;
0163   pthread_t           id;
0164   pthread_attr_t      attr;
0165   struct sched_param  param;
0166   Test_t             *test;
0167   struct sigaction    act;
0168   struct timespec     delay_request;
0169 
0170   TEST_BEGIN();
0171 
0172   Signal_occurred = false;
0173 
0174   block_all_signals();
0175 
0176   act.sa_handler = Signal_handler;
0177   act.sa_flags   = 0;
0178   sigaction( SIGUSR1, &act, NULL );
0179 
0180   puts( "Init - Raise my priority" );
0181   sc = pthread_attr_init( &attr );
0182   rtems_test_assert( !sc );
0183 
0184   param.sched_priority = 30;
0185   sc = pthread_setschedparam( pthread_self(), SCHED_RR, &param );
0186   rtems_test_assert( !sc );
0187 
0188   for ( i=0, test=Threads ; test->priority != -1 ; i++, test++ ) {
0189     printf( "Init - Create thread %d, priority=%d\n", i, test->priority );
0190     sc = pthread_attr_init( &attr );
0191     rtems_test_assert( !sc );
0192 
0193     sc = pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
0194     rtems_test_assert( !sc );
0195 
0196     sc = pthread_attr_setschedpolicy( &attr, SCHED_RR );
0197     rtems_test_assert( !sc );
0198 
0199     param.sched_priority = test->priority;
0200     sc = pthread_attr_setschedparam( &attr, &param );
0201     rtems_test_assert( !sc );
0202 
0203     sc = pthread_create( &id, &attr, Test_Thread, test );
0204     rtems_test_assert( !sc );
0205 
0206     puts( "Init - sleep - let thread settle - OK" );
0207     delay_request.tv_sec = 0;
0208     delay_request.tv_nsec = 50000000;
0209     sc = nanosleep( &delay_request, NULL );
0210     rtems_test_assert( !sc );
0211   }
0212 
0213   puts( "Init - sending SIGUSR1" );
0214   sc =  kill( getpid(), SIGUSR1 );
0215   rtems_test_assert( !sc );
0216 
0217   /* we are just scheduling the signal, not delivering it */
0218   rtems_test_assert( Signal_occurred == false );
0219 
0220   TEST_END();
0221   rtems_test_exit(0);
0222 
0223   return NULL; /* just so the compiler thinks we returned something */
0224 }
0225 
0226 /* configuration information */
0227 
0228 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0229 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0230 
0231 #define CONFIGURE_MICROSECONDS_PER_TICK        1000
0232 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0233 
0234 #define CONFIGURE_MAXIMUM_POSIX_THREADS        9
0235 
0236 #define CONFIGURE_POSIX_INIT_THREAD_TABLE
0237 
0238 #define CONFIGURE_INIT
0239 #include <rtems/confdefs.h>