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