]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/test/nptl/tst-signal3.c
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / test / nptl / tst-signal3.c
1 /* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #include <errno.h>
21 #include <pthread.h>
22 #include <semaphore.h>
23 #include <signal.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27
28
29 /* Number of different signalss to use.  Also is the number of
30    threads.  */
31 #define N 10
32 /* Maximum number of threads in flight at any one time.  */
33 #define INFLIGHT 5
34 /* Number of signals sent in total.  */
35 #define ROUNDS 10000
36
37
38 static int received[N][N];
39 static int nsig[N];
40 static pthread_t th[N];
41 static sem_t sem;
42 static pthread_mutex_t lock[N];
43 static pthread_t th_main;
44 static int sig0;
45
46 static void
47 handler (int sig)
48 {
49   int i;
50   for (i = 0; i < N; ++i)
51     if (pthread_equal (pthread_self (), th[i]))
52       break;
53
54   if (i == N)
55     {
56       if (pthread_equal (pthread_self (), th_main))
57         puts ("signal received by main thread");
58       else
59         printf ("signal received by unknown thread (%lx)\n",
60                 (unsigned long int) pthread_self ());
61       exit (1);
62     }
63
64   ++received[i][sig - sig0];
65
66   sem_post (&sem);
67 }
68
69
70 static void *
71 tf (void *arg)
72 {
73   int idx = (long int) arg;
74
75   sigset_t ss;
76   sigemptyset (&ss);
77
78   int i;
79   for (i = 0; i <= idx; ++i)
80     sigaddset (&ss, sig0 + i);
81
82   if (pthread_sigmask (SIG_UNBLOCK, &ss, NULL) != 0)
83     {
84       printf ("thread %d: pthread_sigmask failed\n", i);
85       exit (1);
86     }
87
88   pthread_mutex_lock (&lock[idx]);
89
90   return NULL;
91 }
92
93
94 static int
95 do_test (void)
96 {
97   /* Block all signals.  */
98   sigset_t ss;
99   sigfillset (&ss);
100
101   th_main = pthread_self ();
102
103   sig0 = SIGRTMIN;
104
105   if (pthread_sigmask (SIG_SETMASK, &ss, NULL) != 0)
106     {
107       puts ("1st pthread_sigmask failed");
108       exit (1);
109     }
110
111   /* Install the handler.  */
112   int i;
113   for (i = 0; i < N; ++i)
114     {
115       struct sigaction sa =
116         {
117           .sa_handler = handler,
118           .sa_flags = 0
119         };
120       sigfillset (&sa.sa_mask);
121
122       if (sigaction (sig0 + i, &sa, NULL) != 0)
123         {
124           printf ("sigaction for signal %d failed\n", i);
125           exit (1);
126         }
127     }
128
129   if (sem_init (&sem, 0, INFLIGHT) != 0)
130     {
131       puts ("sem_init failed");
132       exit (1);
133     }
134
135   pthread_attr_t a;
136
137   if (pthread_attr_init (&a) != 0)
138     {
139       puts ("attr_init failed");
140       exit (1);
141     }
142
143   if (pthread_attr_setstacksize (&a, 1 * 1024 * 1024) != 0)
144     {
145       puts ("attr_setstacksize failed");
146       return 1;
147     }
148
149   for (i = 0; i < N; ++i)
150     {
151       if (pthread_mutex_init (&lock[i], NULL) != 0)
152         {
153           printf ("mutex_init[%d] failed\n", i);
154         }
155
156       if (pthread_mutex_lock (&lock[i]) != 0)
157         {
158           printf ("mutex_lock[%d] failed\n", i);
159         }
160
161       if (pthread_create (&th[i], &a, tf, (void *) (long int) i) != 0)
162         {
163           printf ("create of thread %d failed\n", i);
164           exit (1);
165         }
166     }
167
168   if (pthread_attr_destroy (&a) != 0)
169     {
170       puts ("attr_destroy failed");
171       exit (1);
172     }
173
174   int result = 0;
175   unsigned int r = 42;
176   pid_t pid = getpid ();
177
178   for (i = 0; i < ROUNDS; ++i)
179     {
180       if (TEMP_FAILURE_RETRY (sem_wait (&sem)) != 0)
181         {
182           printf ("sem_wait round %d failed: %m\n", i);
183           exit (1);
184         }
185
186       int s = rand_r (&r) % N;
187
188       kill (pid, sig0 + s);
189     }
190
191   void *status;
192   for (i = 0; i < N; ++i)
193     {
194       if (pthread_mutex_unlock (&lock[i]) != 0)
195         {
196           printf ("unlock %d failed\n", i);
197           exit (1);
198         }
199
200       if (pthread_join (th[i], &status) != 0)
201         {
202           printf ("join %d failed\n", i);
203           result = 1;
204         }
205       else if (status != NULL)
206         {
207           printf ("%d: result != NULL\n", i);
208           result = 1;
209         }
210     }
211
212   int total = 0;
213   for (i = 0; i < N; ++i)
214     {
215       int j;
216
217       for (j = 0; j <= i; ++j)
218         total += received[i][j];
219
220       for (j = i + 1; j < N; ++j)
221         if (received[i][j] != 0)
222           {
223             printf ("thread %d received signal SIGRTMIN+%d\n", i, j);
224             result = 1;
225           }
226     }
227
228   if (total != ROUNDS)
229     {
230       printf ("total number of handled signals is %d, expected %d\n",
231               total, ROUNDS);
232       result = 1;
233     }
234
235   printf ("A total of %d signals sent and received\n", total);
236   for (i = 0; i < N; ++i)
237     {
238       printf ("thread %2d:", i);
239
240       int j;
241       for (j = 0; j <= i; ++j)
242         {
243           printf (" %5d", received[i][j]);
244           nsig[j] += received[i][j];
245         }
246
247       putchar ('\n');
248
249     }
250
251   printf ("\nTotal    :");
252   for (i = 0; i < N; ++i)
253     printf (" %5d", nsig[i]);
254   putchar ('\n');
255
256   return result;
257 }
258
259 #define TIMEOUT 10
260 #define TEST_FUNCTION do_test ()
261 #include "../test-skeleton.c"