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