Update year range in copyright notice of all files owned by the GDB project.
[deliverable/binutils-gdb.git] / gdb / testsuite / gdb.threads / tls.c
CommitLineData
8bc2021f
EZ
1/* BeginSourceFile tls.c
2
3 This file creates and deletes threads. It uses thread local storage
4 variables too. */
5
6#include <unistd.h>
7#include <stdlib.h>
8#include <stdio.h>
9#include <assert.h>
10#include <pthread.h>
11#include <semaphore.h>
12#include <errno.h>
13
14#define N_THREADS 3
15
16/* Uncomment to turn on debugging output */
17/*#define START_DEBUG*/
18
19/* Thread-local storage. */
20__thread int a_thread_local;
515ed532
TT
21
22class K {
23 public:
24 static __thread int another_thread_local;
25};
26
27__thread int K::another_thread_local;
8bc2021f 28
e0740f77
JK
29/* psymtabs->symtabs resolving check. */
30extern __thread int file2_thread_local;
31
8bc2021f
EZ
32/* Global variable just for info addr in gdb. */
33int a_global;
34
35/* Print the results of thread-local storage. */
36int thread_local_val[ N_THREADS ];
37int another_thread_local_val[ N_THREADS ];
38
39/* Semaphores to make sure the threads are alive when we print the TLS
40 variables from gdb. */
41sem_t tell_main, tell_thread;
42
43
44void print_error ()
45{
46 switch (errno)
47 {
48 case EAGAIN:
49 fprintf (stderr, "EAGAIN\n");
50 break;
51 case EINTR:
52 fprintf (stderr, "EINTR\n");
53 break;
54 case EINVAL:
55 fprintf (stderr, "EINVAL\n");
56 break;
57 case ENOSYS:
58 fprintf (stderr, "ENOSYS\n");
59 break;
60 case ENOENT:
61 fprintf (stderr, "ENOENT\n");
62 break;
63 case EDEADLK:
64 fprintf (stderr, "EDEADLK\n");
65 break;
66 default:
67 fprintf (stderr, "Unknown error\n");
68 break;
69 }
70}
71
72/* Routine for each thread to run, does nothing. */
515ed532 73void *spin( void *vp )
8bc2021f
EZ
74{
75 int me = (long) vp;
76 int i;
77
78 /* Use a_global. */
79 a_global++;
80
81 a_thread_local = 0;
515ed532 82 K::another_thread_local = me;
8bc2021f
EZ
83 for( i = 0; i <= me; i++ ) {
84 a_thread_local += i;
85 }
86
515ed532 87 another_thread_local_val[me] = K::another_thread_local;
8bc2021f
EZ
88 thread_local_val[ me ] = a_thread_local; /* here we know tls value */
89
90 if (sem_post (&tell_main) == -1)
91 {
92 fprintf (stderr, "th %d post on sem tell_main failed\n", me);
93 print_error ();
515ed532 94 return NULL;
8bc2021f
EZ
95 }
96#ifdef START_DEBUG
97 fprintf (stderr, "th %d post on tell main\n", me);
98#endif
99
51514e06 100 while (1)
8bc2021f 101 {
8bc2021f
EZ
102#ifdef START_DEBUG
103 fprintf (stderr, "th %d start wait on tell_thread\n", me);
104#endif
51514e06
MC
105 if (sem_wait (&tell_thread) == 0)
106 break;
107
108 if (errno == EINTR)
109 {
8bc2021f 110#ifdef START_DEBUG
51514e06 111 fprintf (stderr, "th %d wait tell_thread got EINTR, rewaiting\n", me);
8bc2021f 112#endif
51514e06
MC
113 continue;
114 }
115 else
116 {
117 fprintf (stderr, "th %d wait on sem tell_thread failed\n", me);
118 print_error ();
515ed532 119 return NULL;
8bc2021f
EZ
120 }
121 }
8bc2021f
EZ
122
123#ifdef START_DEBUG
124 fprintf (stderr, "th %d Wait on tell_thread\n", me);
125#endif
126
515ed532 127 return NULL;
8bc2021f
EZ
128}
129
e0740f77
JK
130void
131function_referencing_file2_thread_local (void)
132{
133 file2_thread_local = file2_thread_local;
134}
135
8bc2021f
EZ
136void
137do_pass()
138{
139 int i;
140 pthread_t t[ N_THREADS ];
141 int err;
142
143 for( i = 0; i < N_THREADS; i++)
144 {
145 thread_local_val[i] = 0;
146 another_thread_local_val[i] = 0;
147 }
148
149 if (sem_init (&tell_main, 0, 0) == -1)
150 {
151 fprintf (stderr, "tell_main semaphore init failed\n");
152 return;
153 }
154
155 if (sem_init (&tell_thread, 0, 0) == -1)
156 {
157 fprintf (stderr, "tell_thread semaphore init failed\n");
158 return;
159 }
160
161 /* Start N_THREADS threads, then join them so that they are terminated. */
162 for( i = 0; i < N_THREADS; i++ )
163 {
164 err = pthread_create( &t[i], NULL, spin, (void *) (long) i );
165 if( err != 0 ) {
166 fprintf(stderr, "Error in thread %d create\n", i );
167 }
168 }
169
170 for( i = 0; i < N_THREADS; i++ )
51514e06
MC
171 {
172 while (1)
173 {
8bc2021f 174#ifdef START_DEBUG
51514e06 175 fprintf (stderr, "main %d start wait on tell_main\n", i);
8bc2021f 176#endif
51514e06
MC
177 if (sem_wait (&tell_main) == 0)
178 break;
8bc2021f 179
51514e06
MC
180 if (errno == EINTR)
181 {
8bc2021f 182#ifdef START_DEBUG
51514e06 183 fprintf (stderr, "main %d wait tell_main got EINTR, rewaiting\n", i);
8bc2021f 184#endif
51514e06
MC
185 continue;
186 }
187 else
188 {
189 fprintf (stderr, "main %d wait on sem tell_main failed\n", i);
190 print_error ();
191 return;
192 }
193 }
194 }
8bc2021f
EZ
195
196#ifdef START_DEBUG
197 fprintf (stderr, "main done waiting on tell_main\n");
198#endif
199
200 i = 10; /* Here all threads should be still alive. */
201
202 for( i = 0; i < N_THREADS; i++ )
203 {
204 if (sem_post (&tell_thread) == -1)
205 {
206 fprintf (stderr, "main %d post on sem tell_thread failed\n", i);
207 print_error ();
208 return;
209 }
210#ifdef START_DEBUG
211 fprintf (stderr, "main %d post on tell_thread\n", i);
212#endif
213 }
214
215 for( i = 0; i < N_THREADS; i++ )
216 {
217 err = pthread_join(t[i], NULL );
218 if( err != 0 )
219 {
220 fprintf (stderr, "error in thread %d join\n", i );
221 }
222 }
223
224 i = 10; /* Null line for setting bpts on. */
225
226}
227
228int
229main()
230{
231 do_pass ();
232
233 return 0; /* Set breakpoint here before exit. */
234}
235
236/* EndSourceFile */
This page took 1.382855 seconds and 4 git commands to generate.