~ubuntu-branches/ubuntu/utopic/gettext/utopic

« back to all changes in this revision

Viewing changes to gettext-tools/gnulib-tests/test-tls.c

  • Committer: Colin Watson
  • Date: 2010-08-01 21:36:08 UTC
  • mfrom: (2.1.10 sid)
  • Revision ID: cjwatson@canonical.com-20100801213608-yy7vkm8lpatep3ci
merge from Debian 0.18.1.1-1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* Test of thread-local storage in multithreaded situations.
2
 
   Copyright (C) 2005 Free Software Foundation, Inc.
 
2
   Copyright (C) 2005, 2008-2010 Free Software Foundation, Inc.
3
3
 
4
4
   This program is free software: you can redistribute it and/or modify
5
5
   it under the terms of the GNU General Public License as published by
50
50
#include <stdlib.h>
51
51
#include <string.h>
52
52
 
53
 
#include "tls.h"
 
53
#include "glthread/tls.h"
 
54
#include "glthread/thread.h"
 
55
#include "glthread/yield.h"
54
56
 
55
57
#if ENABLE_DEBUGGING
56
58
# define dbgprintf printf
58
60
# define dbgprintf if (0) printf
59
61
#endif
60
62
 
61
 
#if TEST_POSIX_THREADS
62
 
# include <pthread.h>
63
 
# include <sched.h>
64
 
typedef pthread_t gl_thread_t;
65
 
static inline gl_thread_t gl_thread_create (void * (*func) (void *), void *arg)
66
 
{
67
 
  pthread_t thread;
68
 
  if (pthread_create (&thread, NULL, func, arg) != 0)
69
 
    abort ();
70
 
  return thread;
71
 
}
72
 
static inline void gl_thread_join (gl_thread_t thread)
73
 
{
74
 
  void *retval;
75
 
  if (pthread_join (thread, &retval) != 0)
76
 
    abort ();
77
 
}
78
 
static inline void gl_thread_yield (void)
79
 
{
80
 
  sched_yield ();
81
 
}
82
 
static inline void * gl_thread_self (void)
83
 
{
84
 
  return (void *) pthread_self ();
85
 
}
86
 
#endif
87
 
#if TEST_PTH_THREADS
88
 
# include <pth.h>
89
 
typedef pth_t gl_thread_t;
90
 
static inline gl_thread_t gl_thread_create (void * (*func) (void *), void *arg)
91
 
{
92
 
  pth_t thread = pth_spawn (NULL, func, arg);
93
 
  if (thread == NULL)
94
 
    abort ();
95
 
  return thread;
96
 
}
97
 
static inline void gl_thread_join (gl_thread_t thread)
98
 
{
99
 
  if (!pth_join (thread, NULL))
100
 
    abort ();
101
 
}
102
 
static inline void gl_thread_yield (void)
103
 
{
104
 
  pth_yield (NULL);
105
 
}
106
 
static inline void * gl_thread_self (void)
107
 
{
108
 
  return pth_self ();
109
 
}
110
 
#endif
111
 
#if TEST_SOLARIS_THREADS
112
 
# include <thread.h>
113
 
typedef thread_t gl_thread_t;
114
 
static inline gl_thread_t gl_thread_create (void * (*func) (void *), void *arg)
115
 
{
116
 
  thread_t thread;
117
 
  if (thr_create (NULL, 0, func, arg, 0, &thread) != 0)
118
 
    abort ();
119
 
  return thread;
120
 
}
121
 
static inline void gl_thread_join (gl_thread_t thread)
122
 
{
123
 
  void *retval;
124
 
  if (thr_join (thread, NULL, &retval) != 0)
125
 
    abort ();
126
 
}
127
 
static inline void gl_thread_yield (void)
128
 
{
129
 
  thr_yield ();
130
 
}
131
 
static inline void * gl_thread_self (void)
132
 
{
133
 
  return (void *) thr_self ();
134
 
}
135
 
#endif
136
 
#if TEST_WIN32_THREADS
137
 
# include <windows.h>
138
 
typedef HANDLE gl_thread_t;
139
 
/* Use a wrapper function, instead of adding WINAPI through a cast.  */
140
 
struct wrapper_args { void * (*func) (void *); void *arg; };
141
 
static DWORD WINAPI wrapper_func (void *varg)
142
 
{
143
 
  struct wrapper_args *warg = (struct wrapper_args *)varg;
144
 
  void * (*func) (void *) = warg->func;
145
 
  void *arg = warg->arg;
146
 
  free (warg);
147
 
  func (arg);
148
 
  return 0;
149
 
}
150
 
static inline gl_thread_t gl_thread_create (void * (*func) (void *), void *arg)
151
 
{
152
 
  struct wrapper_args *warg =
153
 
    (struct wrapper_args *) malloc (sizeof (struct wrapper_args));
154
 
  if (warg == NULL)
155
 
    abort ();
156
 
  warg->func = func;
157
 
  warg->arg = arg;
158
 
  {
159
 
    DWORD thread_id;
160
 
    HANDLE thread =
161
 
      CreateThread (NULL, 100000, wrapper_func, warg, 0, &thread_id);
162
 
    if (thread == NULL)
163
 
      abort ();
164
 
    return thread;
165
 
  }
166
 
}
167
 
static inline void gl_thread_join (gl_thread_t thread)
168
 
{
169
 
  if (WaitForSingleObject (thread, INFINITE) == WAIT_FAILED)
170
 
    abort ();
171
 
  if (!CloseHandle (thread))
172
 
    abort ();
173
 
}
174
 
static inline void gl_thread_yield (void)
175
 
{
176
 
  Sleep (0);
177
 
}
178
 
static inline void * gl_thread_self (void)
179
 
{
180
 
  return (void *) GetCurrentThreadId ();
181
 
}
182
 
#endif
183
63
#if EXPLICIT_YIELD
184
64
# define yield() gl_thread_yield ()
185
65
#else
195
75
    yield ();
196
76
}
197
77
 
 
78
 
 
79
/* ----------------------- Test thread-local storage ----------------------- */
 
80
 
198
81
#define KEYS_COUNT 4
199
82
 
200
83
static gl_tls_key_t mykeys[KEYS_COUNT];
211
94
  /* Initialize the per-thread storage.  */
212
95
  for (i = 0; i < KEYS_COUNT; i++)
213
96
    {
214
 
      values[i] = (((unsigned int) rand() >> 3) % 1000000) * THREAD_COUNT + id;
 
97
      values[i] = (((unsigned int) rand () >> 3) % 1000000) * THREAD_COUNT + id;
215
98
      /* Hopefully no arithmetic overflow.  */
216
99
      if ((values[i] % THREAD_COUNT) != id)
217
 
        abort ();
 
100
        abort ();
218
101
    }
219
102
  perhaps_yield ();
220
103
 
241
124
  for (repeat = REPEAT_COUNT; repeat > 0; repeat--)
242
125
    {
243
126
      dbgprintf ("Worker %p doing value swapping\n", gl_thread_self ());
244
 
      i = ((unsigned int) rand() >> 3) % KEYS_COUNT;
245
 
      j = ((unsigned int) rand() >> 3) % KEYS_COUNT;
 
127
      i = ((unsigned int) rand () >> 3) % KEYS_COUNT;
 
128
      j = ((unsigned int) rand () >> 3) % KEYS_COUNT;
246
129
      if (i != j)
247
 
        {
248
 
          void *vi = gl_tls_get (mykeys[i]);
249
 
          void *vj = gl_tls_get (mykeys[j]);
 
130
        {
 
131
          void *vi = gl_tls_get (mykeys[i]);
 
132
          void *vj = gl_tls_get (mykeys[j]);
250
133
 
251
 
          gl_tls_set (mykeys[i], vj);
252
 
          gl_tls_set (mykeys[j], vi);
253
 
        }
 
134
          gl_tls_set (mykeys[i], vj);
 
135
          gl_tls_set (mykeys[j], vi);
 
136
        }
254
137
      perhaps_yield ();
255
138
    }
256
139
 
266
149
  return NULL;
267
150
}
268
151
 
269
 
void
 
152
static void
270
153
test_tls (void)
271
154
{
272
155
  int pass, i;
276
159
      gl_thread_t threads[THREAD_COUNT];
277
160
 
278
161
      if (pass == 0)
279
 
        for (i = 0; i < KEYS_COUNT; i++)
280
 
          gl_tls_key_init (mykeys[i], free);
 
162
        for (i = 0; i < KEYS_COUNT; i++)
 
163
          gl_tls_key_init (mykeys[i], free);
281
164
      else
282
 
        for (i = KEYS_COUNT - 1; i >= 0; i--)
283
 
          gl_tls_key_init (mykeys[i], free);
 
165
        for (i = KEYS_COUNT - 1; i >= 0; i--)
 
166
          gl_tls_key_init (mykeys[i], free);
284
167
 
285
168
      /* Spawn the threads.  */
286
169
      for (i = 0; i < THREAD_COUNT; i++)
287
 
        threads[i] = gl_thread_create (worker_thread, NULL);
 
170
        threads[i] = gl_thread_create (worker_thread, NULL);
288
171
 
289
172
      /* Wait for the threads to terminate.  */
290
173
      for (i = 0; i < THREAD_COUNT; i++)
291
 
        gl_thread_join (threads[i]);
 
174
        gl_thread_join (threads[i], NULL);
292
175
 
293
176
      for (i = 0; i < KEYS_COUNT; i++)
294
 
        gl_tls_key_destroy (mykeys[i]);
 
177
        gl_tls_key_destroy (mykeys[i]);
295
178
    }
296
179
}
297
180
 
 
181
 
 
182
/* -------------------------------------------------------------------------- */
 
183
 
298
184
int
299
185
main ()
300
186
{
314
200
 
315
201
/* No multithreading available.  */
316
202
 
 
203
#include <stdio.h>
 
204
 
317
205
int
318
206
main ()
319
207
{
 
208
  fputs ("Skipping test: multithreading not enabled\n", stderr);
320
209
  return 77;
321
210
}
322
211