OSDN Git Service

Merge branch 'master' into nptl
[uclinux-h8/uclibc-ng.git] / test / nptl / tst-kill6.c
1 /* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
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 static pthread_t receiver;
30 static sem_t sem;
31 static pthread_barrier_t b;
32
33 static void
34 handler (int sig)
35 {
36   if (sig != SIGUSR1)
37     {
38       write (STDOUT_FILENO, "wrong signal\n", 13);
39       _exit (1);
40     }
41
42   if (pthread_self () != receiver)
43     {
44       write (STDOUT_FILENO, "not the intended receiver\n", 26);
45       _exit (1);
46     }
47
48   if (sem_post (&sem) != 0)
49     {
50       write (STDOUT_FILENO, "sem_post failed\n", 16);
51       _exit (1);
52     }
53 }
54
55
56 static void *
57 tf (void *a)
58 {
59   int e = pthread_barrier_wait (&b);
60   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
61     {
62       puts ("child: barrier_wait failed");
63       exit (1);
64     }
65
66   return NULL;
67 }
68
69
70 int
71 do_test (void)
72 {
73   struct sigaction sa;
74   sigemptyset (&sa.sa_mask);
75   sa.sa_flags = 0;
76   sa.sa_handler = handler;
77   if (sigaction (SIGUSR1, &sa, NULL) != 0)
78     {
79       puts ("sigaction failed");
80       exit (1);
81     }
82
83 #define N 20
84
85   if (pthread_barrier_init (&b, NULL, N + 1) != 0)
86     {
87       puts ("barrier_init failed");
88       exit (1);
89     }
90
91   pthread_attr_t a;
92
93   if (pthread_attr_init (&a) != 0)
94     {
95       puts ("attr_init failed");
96       exit (1);
97     }
98
99   if (pthread_attr_setstacksize (&a, 1 * 1024 * 1024) != 0)
100     {
101       puts ("attr_setstacksize failed");
102       return 1;
103     }
104
105   pthread_t th[N];
106   int i;
107   for (i = 0; i < N; ++i)
108     if (pthread_create (&th[i], &a, tf, NULL) != 0)
109       {
110         puts ("create failed");
111         exit (1);
112       }
113
114   if (pthread_attr_destroy (&a) != 0)
115     {
116       puts ("attr_destroy failed");
117       exit (1);
118     }
119
120   if (sem_init (&sem, 0, 0) != 0)
121     {
122       puts ("sem_init failed");
123       exit (1);
124     }
125
126   for (i = 0; i < N * 10; ++i)
127     {
128       receiver = th[i % N];
129
130       if (pthread_kill (receiver, SIGUSR1) != 0)
131         {
132           puts ("kill failed");
133           exit (1);
134         }
135
136       if (TEMP_FAILURE_RETRY (sem_wait (&sem)) != 0)
137         {
138           puts ("sem_wait failed");
139           exit (1);
140         }
141     }
142
143   int e = pthread_barrier_wait (&b);
144   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
145     {
146       puts ("barrier_wait failed");
147       exit (1);
148     }
149
150   for (i = 0; i < N; ++i)
151     if (pthread_join (th[i], NULL) != 0)
152       {
153         puts ("join failed");
154         exit (1);
155       }
156
157   return 0;
158 }
159
160
161 #define TEST_FUNCTION do_test ()
162 #include "../test-skeleton.c"