implemented Setup.hs to build boehm cpp libs and install them;
[hs-boehmgc.git] / gc-7.2 / tests / threadkey_test.c
1
2 #ifdef HAVE_CONFIG_H
3 # include "private/config.h"
4 #endif
5
6 #ifndef GC_THREADS
7 # define GC_THREADS
8 #endif
9
10 #define GC_NO_THREAD_REDIRECTS 1
11
12 #include "gc.h"
13
14 #if (!defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS) \
15      || defined(__native_client__)) && !defined(SKIP_THREADKEY_TEST)
16   /* FIXME: Skip this test on Solaris for now.  The test may fail on    */
17   /* other targets as well.  Currently, tested only on Linux, Cygwin    */
18   /* and Darwin.                                                        */
19 # define SKIP_THREADKEY_TEST
20 #endif
21
22 #ifdef SKIP_THREADKEY_TEST
23
24 #include <stdio.h>
25
26 int main (void)
27 {
28   printf("threadkey_test skipped\n");
29   return 0;
30 }
31
32 #else
33
34 #include <pthread.h>
35
36 pthread_key_t key;
37
38 #ifdef GC_SOLARIS_THREADS
39   /* pthread_once_t key_once = { PTHREAD_ONCE_INIT }; */
40 #else
41   pthread_once_t key_once = PTHREAD_ONCE_INIT;
42 #endif
43
44 void * entry (void *arg)
45 {
46   pthread_setspecific(key,
47                       (void *)GC_HIDE_POINTER(GC_STRDUP("hello, world")));
48   return arg;
49 }
50
51 void * GC_CALLBACK on_thread_exit_inner (struct GC_stack_base * sb, void * arg)
52 {
53   int res = GC_register_my_thread (sb);
54   pthread_t t;
55   int creation_res;     /* Used to suppress a warning about     */
56                         /* unchecked pthread_create() result.   */
57
58   creation_res = GC_pthread_create (&t, NULL, entry, NULL);
59   if (res == GC_SUCCESS)
60     GC_unregister_my_thread ();
61
62   return (void*)(GC_word)creation_res;
63 }
64
65 void on_thread_exit (void *v)
66 {
67   GC_call_with_stack_base (on_thread_exit_inner, NULL);
68 }
69
70 void make_key (void)
71 {
72   pthread_key_create (&key, on_thread_exit);
73 }
74
75 #ifndef LIMIT
76 # define LIMIT 30
77 #endif
78
79 int main (void)
80 {
81   int i;
82   GC_INIT ();
83
84 # ifdef GC_SOLARIS_THREADS
85     pthread_key_create (&key, on_thread_exit);
86 # else
87     pthread_once (&key_once, make_key);
88 # endif
89   for (i = 0; i < LIMIT; i++) {
90     pthread_t t;
91     void *res;
92     if (GC_pthread_create (&t, NULL, entry, NULL) == 0
93         && (i & 1) != 0)
94       GC_pthread_join (t, &res);
95   }
96   return 0;
97 }
98
99 #endif /* !SKIP_THREADKEY_TEST */