source: rtems/testsuites/psxtests/psxsignal03/init.c @ 8798372

5
Last change on this file since 8798372 was 8798372, checked in by Joel Sherrill <joel@…>, on 09/10/19 at 17:53:31

Correct initial POSIX signals mask

+ Modify POSIX thread create extension to ensure expected

initial signal mask is provided to system threads, initial
tasks and threads, and inheritied by tasks and threads.

+ Adds psxsignal07 to verify functionality when using a POSIX

Initialization thread and POSIX threads.

+ Adds psxsignal08 to verify functionality when using a Classic API

Initialization task and Classic API tasks.

Closes #3794.

  • Property mode set to 100644
File size: 6.6 KB
Line 
1/*
2 *  COPYRIGHT (c) 1989-2012.
3 *  On-Line Applications Research Corporation (OAR).
4 *
5 *  The license and distribution terms for this file may be
6 *  found in the file LICENSE in this distribution or at
7 *  http://www.rtems.org/license/LICENSE.
8 */
9
10#ifdef HAVE_CONFIG_H
11#include "config.h"
12#endif
13
14#if defined(USE_USER_SIGNALS_PROCESS)
15  #define TEST_NAME                "PSXSIGNAL 3"
16  #define TEST_STRING              "User Signals to Process"
17  #define SIGNAL_ONE               SIGUSR1
18  #define SIGNAL_TWO               SIGUSR2
19  #define SEND_SIGNAL(_sig)        kill( getpid(), _sig )
20  #define TO_PROCESS
21
22#elif defined(USE_REAL_TIME_SIGNALS_PROCESS)
23  #define TEST_NAME                "PSXSIGNAL 4"
24  #define TEST_STRING              "Real-Time Signals to Process"
25  #define SIGNAL_ONE               SIGRTMIN
26  #define SIGNAL_TWO               SIGRTMAX
27  #define SEND_SIGNAL(_sig)        kill( getpid(), _sig )
28  #define TO_PROCESS
29
30#elif defined(USE_USER_SIGNALS_THREAD)
31  #define TEST_NAME                "PSXSIGNAL 5"
32  #define TEST_STRING              "User Signals to Thread"
33  #define SIGNAL_ONE               SIGUSR1
34  #define SIGNAL_TWO               SIGUSR2
35  #define SEND_SIGNAL(_sig)        pthread_kill( id, _sig )
36  #define TO_THREAD
37
38#elif defined(USE_REAL_TIME_SIGNALS_THREAD)
39  #define TEST_NAME                "PSXSIGNAL 5"
40  #define TEST_STRING              "Real-Time Signals to Thread"
41  #define SIGNAL_ONE               SIGRTMIN
42  #define SIGNAL_TWO               SIGRTMAX
43  #define SEND_SIGNAL(_sig)        pthread_kill( id, _sig )
44  #define TO_THREAD
45
46#else
47  #error "Test Mode not defined"
48#endif
49
50#include <pmacros.h>
51#include <signal.h>
52#include <errno.h>
53#include <pthread.h>
54#include <sched.h>
55
56const char rtems_test_name[] = TEST_NAME;
57
58/* forward declarations to avoid warnings */
59void *POSIX_Init(void *argument);
60void *Test_Thread(void *arg);
61void Signal_handler(int signo, siginfo_t *info, void *arg);
62const char *signal_name(int signo);
63
64volatile bool      Signal_occurred;
65volatile pthread_t Signal_thread;
66
67static void block_all_signals(void)
68{
69  int               sc;
70  sigset_t          mask;
71
72  sc = sigfillset( &mask );
73  rtems_test_assert( !sc );
74
75  sc = pthread_sigmask( SIG_BLOCK, &mask, NULL );
76  rtems_test_assert( !sc );
77}
78
79void Signal_handler(
80  int        signo,
81  siginfo_t *info,
82  void      *arg
83)
84{
85  Signal_occurred = true;
86  Signal_thread   = pthread_self();
87}
88
89const char *signal_name(int signo)
90{
91  if (signo == SIGUSR1)
92    return "SIGUSR1";
93  if (signo == SIGUSR2)
94    return "SIGUSR2";
95  if (signo == SIGRTMIN)
96    return "SIGRTMIN";
97  if (signo == SIGRTMAX)
98    return "SIGRTMAX";
99  return "unknown-signal";
100}
101
102void *Test_Thread(void *arg)
103{
104  bool        blocked = *((bool *)arg);
105  const char *name;
106  int         sc;
107  sigset_t    mask;
108  sigset_t    wait_mask;
109  siginfo_t   info;
110
111  if ( blocked )
112    name = "SignalBlocked";
113  else
114    name = "SignalNotBlocked";
115
116  /* build unblocked mask */
117  sc = sigemptyset( &mask );
118  rtems_test_assert( !sc );
119
120  printf( "%s - Unblock %s\n", name, signal_name(SIGNAL_ONE) );
121  sc = sigaddset( &mask, SIGNAL_ONE );
122  rtems_test_assert( !sc );
123
124  if ( !blocked ) {
125    printf( "%s - Unblock %s\n", name, signal_name(SIGNAL_TWO) );
126    sc = sigaddset( &mask, SIGNAL_TWO );
127    rtems_test_assert( !sc );
128  }
129
130  /* unblocked signals */
131  sc = pthread_sigmask( SIG_UNBLOCK, &mask, NULL );
132  rtems_test_assert( !sc );
133
134  /* build wait mask */
135  sc = sigemptyset( &wait_mask );
136  rtems_test_assert( !sc );
137
138  sc = sigaddset( &wait_mask, SIGNAL_ONE );
139  rtems_test_assert( !sc );
140
141  /* wait for a signal */
142  memset( &info, 0, sizeof(info) );
143
144  printf( "%s - Wait for %s unblocked\n", name, signal_name(SIGNAL_ONE) );
145  sigwaitinfo( &wait_mask, &info );
146  rtems_test_assert( !sc );
147
148  printf( "%s - siginfo.si_signo=%d\n", name, info.si_signo );
149  printf( "%s - siginfo.si_code=%d\n", name, info.si_code );
150  /* FIXME: Instead of casting to (uintptr_t) and using PRIxPTR, we
151   * likely should use %p. However, this would render this test's
152   * behavior non-deterministic, because %p's behavior is
153   * "implementation defined" */
154  printf(
155    "%s - siginfo.si_value=0x%08" PRIxPTR "\n",
156    name,
157    (uintptr_t) info.si_value.sival_ptr
158  );
159
160  rtems_test_assert( info.si_signo == SIGNAL_TWO );
161  rtems_test_assert( info.si_code == SI_USER );
162
163  printf( "%s - exiting\n", name );
164  return NULL;
165}
166
167void *POSIX_Init(
168  void *argument
169)
170{
171  int                 sc;
172  pthread_t           id;
173  struct sigaction    act;
174  bool                trueArg = true;
175  bool                falseArg = false;
176  struct timespec     delay_request;
177
178  TEST_BEGIN();
179  puts( "Init - Variation is: " TEST_STRING );
180
181  block_all_signals();
182
183  Signal_occurred = false;
184
185  act.sa_handler = NULL;
186  act.sa_sigaction = Signal_handler;
187  act.sa_flags   = SA_SIGINFO;
188  sigaction( SIGNAL_ONE, &act, NULL );
189  sigaction( SIGNAL_TWO, &act, NULL );
190
191  /* create threads */
192  sc = pthread_create( &id, NULL, Test_Thread, &falseArg );
193  rtems_test_assert( !sc );
194
195  sc = pthread_create( &id, NULL, Test_Thread, &trueArg );
196  rtems_test_assert( !sc );
197
198  puts( "Init - sleep - let threads settle - OK" );
199  delay_request.tv_sec = 0;
200  delay_request.tv_nsec = 5 * 100000000;
201  sc = nanosleep( &delay_request, NULL );
202  rtems_test_assert( !sc );
203
204  puts( "Init - sleep - SignalBlocked thread settle - OK" );
205  sc = nanosleep( &delay_request, NULL );
206  rtems_test_assert( !sc );
207
208  printf( "Init - sending %s - deliver to one thread\n",
209          signal_name(SIGNAL_TWO));
210  sc =  SEND_SIGNAL( SIGNAL_TWO );
211  rtems_test_assert( !sc );
212
213  printf( "Init - sending %s - deliver to other thread\n",
214          signal_name(SIGNAL_TWO));
215  sc =  SEND_SIGNAL( SIGNAL_TWO );
216  rtems_test_assert( !sc );
217
218  #if defined(TO_PROCESS)
219    printf( "Init - sending %s - expect EAGAIN\n", signal_name(SIGNAL_TWO) );
220    sc =  SEND_SIGNAL( SIGNAL_TWO );
221    rtems_test_assert( sc == -1 );
222    rtems_test_assert( errno == EAGAIN );
223  #endif
224
225  puts( "Init - sleep - let thread report if it unblocked - OK" );
226  usleep(500000);
227
228  /* we are just sigwait'ing the signal, not delivering it */
229  rtems_test_assert( Signal_occurred == true );
230
231  TEST_END();
232  rtems_test_exit(0);
233
234  return NULL; /* just so the compiler thinks we returned something */
235}
236
237/* configuration information */
238
239#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
240#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
241
242#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
243
244#define CONFIGURE_MAXIMUM_POSIX_THREADS        3
245#define CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS 1
246
247#define CONFIGURE_POSIX_INIT_THREAD_TABLE
248
249#define CONFIGURE_INIT
250#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.