implemented Setup.hs to build boehm cpp libs and install them;
[hs-boehmgc.git] / gc-7.2 / tests / threadkey_test.c
diff --git a/gc-7.2/tests/threadkey_test.c b/gc-7.2/tests/threadkey_test.c
new file mode 100644 (file)
index 0000000..7635424
--- /dev/null
@@ -0,0 +1,99 @@
+
+#ifdef HAVE_CONFIG_H
+# include "private/config.h"
+#endif
+
+#ifndef GC_THREADS
+# define GC_THREADS
+#endif
+
+#define GC_NO_THREAD_REDIRECTS 1
+
+#include "gc.h"
+
+#if (!defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS) \
+     || defined(__native_client__)) && !defined(SKIP_THREADKEY_TEST)
+  /* FIXME: Skip this test on Solaris for now.  The test may fail on    */
+  /* other targets as well.  Currently, tested only on Linux, Cygwin    */
+  /* and Darwin.                                                        */
+# define SKIP_THREADKEY_TEST
+#endif
+
+#ifdef SKIP_THREADKEY_TEST
+
+#include <stdio.h>
+
+int main (void)
+{
+  printf("threadkey_test skipped\n");
+  return 0;
+}
+
+#else
+
+#include <pthread.h>
+
+pthread_key_t key;
+
+#ifdef GC_SOLARIS_THREADS
+  /* pthread_once_t key_once = { PTHREAD_ONCE_INIT }; */
+#else
+  pthread_once_t key_once = PTHREAD_ONCE_INIT;
+#endif
+
+void * entry (void *arg)
+{
+  pthread_setspecific(key,
+                      (void *)GC_HIDE_POINTER(GC_STRDUP("hello, world")));
+  return arg;
+}
+
+void * GC_CALLBACK on_thread_exit_inner (struct GC_stack_base * sb, void * arg)
+{
+  int res = GC_register_my_thread (sb);
+  pthread_t t;
+  int creation_res;     /* Used to suppress a warning about     */
+                        /* unchecked pthread_create() result.   */
+
+  creation_res = GC_pthread_create (&t, NULL, entry, NULL);
+  if (res == GC_SUCCESS)
+    GC_unregister_my_thread ();
+
+  return (void*)(GC_word)creation_res;
+}
+
+void on_thread_exit (void *v)
+{
+  GC_call_with_stack_base (on_thread_exit_inner, NULL);
+}
+
+void make_key (void)
+{
+  pthread_key_create (&key, on_thread_exit);
+}
+
+#ifndef LIMIT
+# define LIMIT 30
+#endif
+
+int main (void)
+{
+  int i;
+  GC_INIT ();
+
+# ifdef GC_SOLARIS_THREADS
+    pthread_key_create (&key, on_thread_exit);
+# else
+    pthread_once (&key_once, make_key);
+# endif
+  for (i = 0; i < LIMIT; i++) {
+    pthread_t t;
+    void *res;
+    if (GC_pthread_create (&t, NULL, entry, NULL) == 0
+        && (i & 1) != 0)
+      GC_pthread_join (t, &res);
+  }
+  return 0;
+}
+
+#endif /* !SKIP_THREADKEY_TEST */