#include <config.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#ifdef HAVE_TLS
#define COUNT 10
static int race;
static __thread int local;
__thread int global;
extern __thread int static_extern;
extern __thread int so_extern;
/* deliberate failure */
static int *test_race(void)
{
return ∽̱
}
static int *test_local(void)
{
return &local;
}
static int *test_global(void)
{
return &global;
}
static int *test_static_extern(void)
{
return &static_extern;
}
static int *test_so_extern(void)
{
return &so_extern;
}
static const struct timespec awhile = { 0, 200000000 };
typedef int *(*func_t)(void);
struct testcase {
const char *name;
func_t func;
char pad[2 * (8 - sizeof(void*))];
};
static void *tls_ptr(void *p)
{
struct testcase *test = (struct testcase *)p;
int *ip = (*test->func)();
int here = 0;
int i;
for(i = 0; i < COUNT; i++) {
int a = (*ip)++;
int b = here++;
if (a != b)
printf("tls_ptr: case \"%s\" has mismatch: *ip=%d here=%d\n",
test->name, a, b);
nanosleep(&awhile, 0);
}
return 0;
}
int *test_so_extern(void);
int *test_so_local(void);
int *test_so_global(void);
static const struct testcase tests[] = {
#define T(t) { #t, test_##t }
T(race),
T(local),
T(global),
T(static_extern),
T(so_extern),
T(so_local),
T(so_global),
#undef T
};
#define NTESTS (sizeof(tests)/sizeof(*tests))
int main()
{
pthread_t threads[NTESTS*2];
int curthread = 0;
static
int i;
for(i = 0; i < NTESTS; i++) {
pthread_create(&threads[curthread++], NULL, tls_ptr, (void *)&tests[i]);
pthread_create(&threads[curthread++], NULL, tls_ptr, (void *)&tests[i]);
}
for(i = 0; i < curthread; i++)
pthread_join(threads[i], NULL);
return 0;
}
#else
int main()
{
printf("FAILED: no compiler support for __thread\n");
return 1;
}
#endif