Update copyright notices with scripts/update-copyrights.
[jlayton/glibc.git] / nptl / tst-tls4.c
1 /* Copyright (C) 2003-2013 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Jakub Jelinek <jakub@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, see
17    <http://www.gnu.org/licenses/>.  */
18
19 #include <dlfcn.h>
20 #include <errno.h>
21 #include <pthread.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <tls.h>
26
27
28 #define N 3
29
30 void (*test1) (void), (*test2) (void);
31
32 pthread_barrier_t b2, b3;
33
34 static void *
35 tf (void *arg)
36 {
37   int i;
38
39   for (i = 0; i <= (uintptr_t) arg; ++i)
40     {
41       int r = pthread_barrier_wait (&b3);
42       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
43         {
44           puts ("tf: barrier_wait failed");
45           exit (1);
46         }
47     }
48
49   test1 ();
50
51   for (i = 0; i < 3; ++i)
52     {
53       int r = pthread_barrier_wait (&b3);
54       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
55         {
56           puts ("tf: barrier_wait failed");
57           exit (1);
58         }
59     }
60
61   test2 ();
62
63   for (i = 0; i < 3 - (uintptr_t) arg; ++i)
64     {
65       int r = pthread_barrier_wait (&b3);
66       if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
67         {
68           puts ("tf: barrier_wait failed");
69           exit (1);
70         }
71     }
72
73   return NULL;
74 }
75
76 static void *
77 tf2 (void *arg)
78 {
79   int r = pthread_barrier_wait (&b2);
80   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
81     {
82       puts ("tf2: barrier_wait failed");
83       exit (1);
84     }
85
86   int i;
87   for (i = 0; i < N; ++i)
88     tf (arg);
89   return NULL;
90 }
91
92 int
93 do_test (void)
94 {
95   pthread_t th[2];
96   const char *modules[N]
97     = { "tst-tls4moda.so", "tst-tls4moda.so", "tst-tls4modb.so" };
98
99   if (pthread_barrier_init (&b2, NULL, 2) != 0)
100     {
101       puts ("barrier_init failed");
102       return 1;
103     }
104
105   if (pthread_barrier_init (&b3, NULL, 3) != 0)
106     {
107       puts ("barrier_init failed");
108       return 1;
109     }
110
111   if (pthread_create (&th[0], NULL, tf2, (void *) (uintptr_t) 1))
112     {
113       puts ("pthread_create failed");
114       return 1;
115     }
116
117   int r = pthread_barrier_wait (&b2);
118   if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
119     {
120       puts ("barrier_wait failed");
121       return 1;
122     }
123
124   int i;
125   for (i = 0; i < N; ++i)
126     {
127       void *h = dlopen (modules[i], RTLD_LAZY);
128       if (h == NULL)
129         {
130           printf ("dlopen failed %s\n", dlerror ());
131           return 1;
132         }
133
134       test1 = dlsym (h, "test1");
135       if (test1 == NULL)
136         {
137           printf ("dlsym for test1 failed %s\n", dlerror ());
138           return 1;
139         }
140
141       test2 = dlsym (h, "test2");
142       if (test2 == NULL)
143         {
144           printf ("dlsym for test2 failed %s\n", dlerror ());
145           return 1;
146         }
147
148       if (pthread_create (&th[1], NULL, tf, (void *) (uintptr_t) 2))
149         {
150           puts ("pthread_create failed");
151           return 1;
152         }
153
154       tf ((void *) (uintptr_t) 0);
155
156       if (pthread_join (th[1], NULL) != 0)
157         {
158           puts ("join failed");
159           return 1;
160         }
161
162       if (dlclose (h))
163         {
164           puts ("dlclose failed");
165           return 1;
166         }
167
168       printf ("test %d with %s succeeded\n", i, modules[i]);
169     }
170
171   if (pthread_join (th[0], NULL) != 0)
172     {
173       puts ("join failed");
174       return 1;
175     }
176
177   return 0;
178 }
179
180 #define TIMEOUT 5
181 #define TEST_FUNCTION do_test ()
182 #include "../test-skeleton.c"