Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Molaro <lupus@oddwiz.org>2006-02-01 20:30:38 +0300
committerPaolo Molaro <lupus@oddwiz.org>2006-02-01 20:30:38 +0300
commitb3d2aabe309eb749fd537c3ee4121e1f3441989d (patch)
tree5c1375e3b27587add692e73f65ea6ec9b4c1fc48 /libgc/pthread_support.c
parent93b73e8c69a093ad675342080b7036aa2e1a7e1b (diff)
Wed Feb 1 18:23:55 CET 2006 Paolo Molaro <lupus@ximian.com>
* pthread_support.c, *: back out Zoltan's patch since it's incorrect. The correct fix it to execute the cleanup from inside the thread also when using the __thread var to access the current GC_thread. svn path=/trunk/mono/; revision=56400
Diffstat (limited to 'libgc/pthread_support.c')
-rw-r--r--libgc/pthread_support.c47
1 files changed, 20 insertions, 27 deletions
diff --git a/libgc/pthread_support.c b/libgc/pthread_support.c
index cef3de4d917..40e6c51b6b2 100644
--- a/libgc/pthread_support.c
+++ b/libgc/pthread_support.c
@@ -84,6 +84,12 @@
# if !defined(USE_PTHREAD_SPECIFIC) && !defined(USE_COMPILER_TLS)
# include "private/specific.h"
# endif
+
+/* Note that these macros should be used only to get/set the GC_thread pointer.
+ * We need to use both tls and pthread because we use the pthread_create function hook to
+ * free the data for foreign threads. When that doesn't happen, libgc could have old
+ * pthread_t that get reused...
+ */
# if defined(USE_PTHREAD_SPECIFIC)
# define GC_getspecific pthread_getspecific
# define GC_setspecific pthread_setspecific
@@ -91,9 +97,9 @@
typedef pthread_key_t GC_key_t;
# endif
# if defined(USE_COMPILER_TLS)
-# define GC_getspecific(x) (x)
-# define GC_setspecific(key, v) ((key) = (v), 0)
-# define GC_key_create(key, d) 0
+# define GC_getspecific(x) (GC_thread_tls)
+# define GC_setspecific(key, v) (GC_thread_tls = (v), pthread_setspecific ((key), (v)))
+# define GC_key_create pthread_key_create
typedef void * GC_key_t;
# endif
# endif
@@ -177,10 +183,11 @@ void GC_init_parallel();
#include "mono/utils/mono-compiler.h"
static
+GC_key_t GC_thread_key;
+
#ifdef USE_COMPILER_TLS
- __thread MONO_TLS_FAST
+static __thread MONO_TLS_FAST void* GC_thread_tls;
#endif
-GC_key_t GC_thread_key;
static GC_bool keys_initialized;
@@ -221,17 +228,19 @@ static void return_freelists(ptr_t *fl, ptr_t *gfl)
/* we arrange for those to fault asap.) */
static ptr_t size_zero_object = (ptr_t)(&size_zero_object);
-void GC_delete_thread(pthread_t id);
+void GC_delete_gc_thread(pthread_t id, GC_thread gct);
-/* Called by pthreads when the TLS entry is destroyed */
-static void GC_thread_deregister_foreign_internal (void *data)
+void GC_thread_deregister_foreign (void *data)
{
GC_thread me = (GC_thread)data;
/* GC_fprintf1( "\n\n\n\n --- Deregister %x ---\n\n\n\n\n", me->flags ); */
if (me -> flags & FOREIGN_THREAD) {
LOCK();
/* GC_fprintf0( "\n\n\n\n --- FOO ---\n\n\n\n\n" ); */
- GC_delete_thread(me->id);
+#if defined(THREAD_LOCAL_ALLOC) && !defined(DBG_HDRS_ALL)
+ GC_destroy_thread_local (me);
+#endif
+ GC_delete_gc_thread(me->id, me);
UNLOCK();
}
}
@@ -244,7 +253,7 @@ void GC_init_thread_local(GC_thread p)
int i;
if (!keys_initialized) {
- if (0 != GC_key_create(&GC_thread_key, GC_thread_deregister_foreign_internal)) {
+ if (0 != GC_key_create(&GC_thread_key, GC_thread_deregister_foreign)) {
ABORT("Failed to create key for local allocator");
}
keys_initialized = TRUE;
@@ -284,7 +293,6 @@ void GC_destroy_thread_local(GC_thread p)
# ifdef GC_GCJ_SUPPORT
return_freelists(p -> gcj_freelists, GC_gcjobjfreelist);
# endif
- GC_setspecific(GC_thread_key, NULL);
}
extern GC_PTR GC_generic_malloc_many();
@@ -673,7 +681,7 @@ void GC_delete_thread(pthread_t id)
int hv = ((word)id) % THREAD_TABLE_SZ;
register GC_thread p = GC_threads[hv];
register GC_thread prev = 0;
-
+
while (!pthread_equal(p -> id, id)) {
prev = p;
p = p -> next;
@@ -1303,21 +1311,6 @@ int GC_thread_register_foreign (void *base_addr)
return me != NULL;
}
-void GC_thread_deregister_foreign (void)
-{
- GC_thread me;
-
- LOCK ();
- me = GC_lookup_thread (pthread_self ());
- if (me->flags & FOREIGN_THREAD) {
- GC_delete_thread (me->id);
-#if defined(THREAD_LOCAL_ALLOC) && !defined(DBG_HDRS_ALL)
- GC_destroy_thread_local (me);
-#endif
- }
- UNLOCK ();
-}
-
void * GC_start_routine(void * arg)
{
int dummy;