2005-07-24 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / libgc / pthread_support.c
index b45341e21095cade2e1e622de3cdff7b334b3182..bece06f139923c2a99e5eb4c66a8bee22ee5e6d1 100644 (file)
@@ -168,9 +168,17 @@ void GC_init_parallel();
 
 /* We don't really support thread-local allocation with DBG_HDRS_ALL */
 
+/* work around a dlopen issue (bug #75390), undefs to avoid warnings with redefinitions */
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+#include "mono/utils/mono-compiler.h"
+
 static
 #ifdef USE_COMPILER_TLS
-  __thread
+  __thread MONO_TLS_FAST
 #endif
 GC_key_t GC_thread_key;
 
@@ -556,6 +564,27 @@ GC_bool GC_thr_initialized = FALSE;
 
 volatile GC_thread GC_threads[THREAD_TABLE_SZ];
 
+/* 
+ * gcc-3.3.6 miscompiles the &GC_thread_key+sizeof(&GC_thread_key) expression so
+ * put it into a separate function.
+ */
+#   if defined(__GNUC__) && defined(THREAD_LOCAL_ALLOC) && !defined(DBG_HDRS_ALL)
+static __attribute__((noinline)) unsigned char* get_gc_thread_key_addr GC_PROTO((void))
+{
+       return (unsigned char*)&GC_thread_key;
+}
+
+void GC_push_thread_structures GC_PROTO((void))
+{
+    GC_push_all((ptr_t)(GC_threads), (ptr_t)(GC_threads)+sizeof(GC_threads));
+#   if defined(THREAD_LOCAL_ALLOC) && !defined(DBG_HDRS_ALL)
+      GC_push_all((ptr_t)get_gc_thread_key_addr(),
+         (ptr_t)(get_gc_thread_key_addr())+sizeof(&GC_thread_key));
+#   endif
+}
+
+#else
+
 void GC_push_thread_structures GC_PROTO((void))
 {
     GC_push_all((ptr_t)(GC_threads), (ptr_t)(GC_threads)+sizeof(GC_threads));
@@ -565,6 +594,8 @@ void GC_push_thread_structures GC_PROTO((void))
 #   endif
 }
 
+#endif
+
 #ifdef THREAD_LOCAL_ALLOC
 /* We must explicitly mark ptrfree and gcj free lists, since the free  */
 /* list links wouldn't otherwise be found.  We also set them in the    */
@@ -676,6 +707,17 @@ GC_thread GC_lookup_thread(pthread_t id)
     return(p);
 }
 
+int GC_thread_is_registered (void)
+{
+       void *ptr;
+
+       LOCK();
+       ptr = (void *)GC_lookup_thread(pthread_self());
+       UNLOCK();
+
+       return ptr ? 1 : 0;
+}
+
 #ifdef HANDLE_FORK
 /* Remove all entries from the GC_threads table, except the    */
 /* one for the current thread.  We need to do this in the child        */