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 #if defined(USE_USER_SIGNALS_PROCESS)
0034   #define TEST_NAME                "PSXSIGNAL 3"
0035   #define TEST_STRING              "User Signals to Process"
0036   #define SIGNAL_ONE               SIGUSR1
0037   #define SIGNAL_TWO               SIGUSR2
0038   #define SEND_SIGNAL(_sig)        kill( getpid(), _sig )
0039   #define TO_PROCESS
0040 
0041 #elif defined(USE_REAL_TIME_SIGNALS_PROCESS)
0042   #define TEST_NAME                "PSXSIGNAL 4"
0043   #define TEST_STRING              "Real-Time Signals to Process"
0044   #define SIGNAL_ONE               SIGRTMIN
0045   #define SIGNAL_TWO               SIGRTMAX
0046   #define SEND_SIGNAL(_sig)        kill( getpid(), _sig )
0047   #define TO_PROCESS
0048 
0049 #else
0050   #error "Test Mode not defined"
0051 #endif
0052 
0053 #include <pmacros.h>
0054 #include <signal.h>
0055 #include <errno.h>
0056 #include <pthread.h>
0057 #include <sched.h>
0058 
0059 const char rtems_test_name[] = TEST_NAME;
0060 
0061 /* forward declarations to avoid warnings */
0062 void *POSIX_Init(void *argument);
0063 void *Test_Thread(void *arg);
0064 void Signal_handler(int signo, siginfo_t *info, void *arg);
0065 const char *signal_name(int signo);
0066 
0067 volatile bool      Signal_occurred;
0068 volatile pthread_t Signal_thread;
0069 
0070 static void block_all_signals(void)
0071 {
0072   int               sc;
0073   sigset_t          mask;
0074 
0075   sc = sigfillset( &mask );
0076   rtems_test_assert( !sc );
0077 
0078   sc = pthread_sigmask( SIG_BLOCK, &mask, NULL );
0079   rtems_test_assert( !sc );
0080 }
0081 
0082 void Signal_handler(
0083   int        signo,
0084   siginfo_t *info,
0085   void      *arg
0086 )
0087 {
0088   Signal_occurred = true;
0089   Signal_thread   = pthread_self();
0090 }
0091 
0092 const char *signal_name(int signo)
0093 {
0094   if (signo == SIGUSR1)
0095     return "SIGUSR1";
0096   if (signo == SIGUSR2)
0097     return "SIGUSR2";
0098   if (signo == SIGRTMIN)
0099     return "SIGRTMIN";
0100   if (signo == SIGRTMAX)
0101     return "SIGRTMAX";
0102   return "unknown-signal";
0103 }
0104 
0105 void *Test_Thread(void *arg)
0106 {
0107   bool        blocked = *((bool *)arg);
0108   const char *name;
0109   int         sc;
0110   sigset_t    mask;
0111   sigset_t    wait_mask;
0112   siginfo_t   info;
0113 
0114   if ( blocked )
0115     name = "SignalBlocked";
0116   else
0117     name = "SignalNotBlocked";
0118 
0119   /* build unblocked mask */
0120   sc = sigemptyset( &mask );
0121   rtems_test_assert( !sc );
0122 
0123   printf( "%s - Unblock %s\n", name, signal_name(SIGNAL_ONE) );
0124   sc = sigaddset( &mask, SIGNAL_ONE );
0125   rtems_test_assert( !sc );
0126 
0127   if ( !blocked ) {
0128     printf( "%s - Unblock %s\n", name, signal_name(SIGNAL_TWO) );
0129     sc = sigaddset( &mask, SIGNAL_TWO );
0130     rtems_test_assert( !sc );
0131   }
0132 
0133   /* unblocked signals */
0134   sc = pthread_sigmask( SIG_UNBLOCK, &mask, NULL );
0135   rtems_test_assert( !sc );
0136 
0137   /* build wait mask */
0138   sc = sigemptyset( &wait_mask );
0139   rtems_test_assert( !sc );
0140 
0141   sc = sigaddset( &wait_mask, SIGNAL_ONE );
0142   rtems_test_assert( !sc );
0143 
0144   /* wait for a signal */
0145   memset( &info, 0, sizeof(info) );
0146 
0147   printf( "%s - Wait for %s unblocked\n", name, signal_name(SIGNAL_ONE) );
0148   sigwaitinfo( &wait_mask, &info );
0149   rtems_test_assert( !sc );
0150 
0151   printf( "%s - siginfo.si_signo=%d\n", name, info.si_signo );
0152   printf( "%s - siginfo.si_code=%d\n", name, info.si_code );
0153   /* FIXME: Instead of casting to (uintptr_t) and using PRIxPTR, we
0154    * likely should use %p. However, this would render this test's
0155    * behavior non-deterministic, because %p's behavior is
0156    * "implementation defined" */
0157   printf(
0158     "%s - siginfo.si_value=0x%08" PRIxPTR "\n",
0159     name,
0160     (uintptr_t) info.si_value.sival_ptr
0161   );
0162 
0163   rtems_test_assert( info.si_signo == SIGNAL_TWO );
0164   rtems_test_assert( info.si_code == SI_USER );
0165 
0166   printf( "%s - exiting\n", name );
0167   return NULL;
0168 }
0169 
0170 void *POSIX_Init(
0171   void *argument
0172 )
0173 {
0174   int                 sc;
0175   pthread_t           id;
0176   struct sigaction    act;
0177   bool                trueArg = true;
0178   bool                falseArg = false;
0179   struct timespec     delay_request;
0180 
0181   TEST_BEGIN();
0182   puts( "Init - Variation is: " TEST_STRING );
0183 
0184   block_all_signals();
0185 
0186   Signal_occurred = false;
0187 
0188   act.sa_handler = NULL;
0189   act.sa_sigaction = Signal_handler;
0190   act.sa_flags   = SA_SIGINFO;
0191   sigaction( SIGNAL_ONE, &act, NULL );
0192   sigaction( SIGNAL_TWO, &act, NULL );
0193 
0194   /* create threads */
0195   sc = pthread_create( &id, NULL, Test_Thread, &falseArg );
0196   rtems_test_assert( !sc );
0197 
0198   sc = pthread_create( &id, NULL, Test_Thread, &trueArg );
0199   rtems_test_assert( !sc );
0200 
0201   puts( "Init - sleep - let threads settle - OK" );
0202   delay_request.tv_sec = 0;
0203   delay_request.tv_nsec = 5 * 100000000;
0204   sc = nanosleep( &delay_request, NULL );
0205   rtems_test_assert( !sc );
0206 
0207   puts( "Init - sleep - SignalBlocked thread settle - OK" );
0208   sc = nanosleep( &delay_request, NULL );
0209   rtems_test_assert( !sc );
0210 
0211   printf( "Init - sending %s - deliver to one thread\n",
0212           signal_name(SIGNAL_TWO));
0213   sc =  SEND_SIGNAL( SIGNAL_TWO );
0214   rtems_test_assert( !sc );
0215 
0216   printf( "Init - sending %s - deliver to other thread\n",
0217           signal_name(SIGNAL_TWO));
0218   sc =  SEND_SIGNAL( SIGNAL_TWO );
0219   rtems_test_assert( !sc );
0220 
0221   #if defined(TO_PROCESS)
0222     printf( "Init - sending %s - expect EAGAIN\n", signal_name(SIGNAL_TWO) );
0223     sc =  SEND_SIGNAL( SIGNAL_TWO );
0224     rtems_test_assert( sc == -1 );
0225     rtems_test_assert( errno == EAGAIN );
0226   #endif
0227 
0228   puts( "Init - sleep - let thread report if it unblocked - OK" );
0229   usleep(500000);
0230 
0231   /* we are just sigwait'ing the signal, not delivering it */
0232   rtems_test_assert( Signal_occurred == true );
0233 
0234   TEST_END();
0235   rtems_test_exit(0);
0236 
0237   return NULL; /* just so the compiler thinks we returned something */
0238 }
0239 
0240 /* configuration information */
0241 
0242 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0243 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0244 
0245 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0246 
0247 #define CONFIGURE_MAXIMUM_POSIX_THREADS        3
0248 #define CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS 1
0249 
0250 #define CONFIGURE_POSIX_INIT_THREAD_TABLE
0251 
0252 #define CONFIGURE_INIT
0253 #include <rtems/confdefs.h>