diff options
author | ivmai <ivmai> | 2011-05-11 07:19:46 +0000 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2011-07-26 21:06:58 +0400 |
commit | 88a952ac5dd3c0582a82a1f2acfa277f5eaf4047 (patch) | |
tree | 44b09f360c494466a599812bd6a70091884763d5 /win32_threads.c | |
parent | d604870504cc8dd8870e8c1a6e719f88eb6c5ba7 (diff) | |
download | bdwgc-88a952ac5dd3c0582a82a1f2acfa277f5eaf4047.tar.gz |
2011-05-11 Ivan Maidanski <ivmai@mail.ru>
* pthread_support.c (GC_unregister_my_thread_inner): Don't call
GC_remove_specific.
* include/private/thread_local_alloc.h (GC_remove_specific):
Remove (since it is empty for all targets).
* pthread_support.c (GC_record_stack_base): New inline function.
* win32_threads.c (GC_record_stack_base): Ditto.
* pthread_support.c (GC_register_my_thread_inner): Invoke
GC_record_stack_base.
* win32_threads.c (GC_register_my_thread_inner): Ditto.
* pthread_support.c (GC_register_my_thread): If thread is FINISHED
then call GC_record_stack_base, clear FINISHED, initialize
thread-local list and return success.
* win32_threads.c (GC_register_my_thread): Ditto.
* include/gc.h (GC_register_my_thread): Update documentation.
* include/private/thread_local_alloc.h (GC_thread_key): Ditto.
Diffstat (limited to 'win32_threads.c')
-rw-r--r-- | win32_threads.c | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/win32_threads.c b/win32_threads.c index a9b406ab..8e0bcc53 100644 --- a/win32_threads.c +++ b/win32_threads.c @@ -364,6 +364,17 @@ STATIC GC_thread GC_new_thread(DWORD id) STATIC GC_bool GC_in_thread_creation = FALSE; /* Protected by allocation lock. */ +GC_INLINE void GC_record_stack_base(GC_vthread me, + const struct GC_stack_base *sb) +{ + me -> stack_base = sb -> mem_base; +# ifdef IA64 + me -> backing_store_end = sb -> reg_base; +# endif + if (me -> stack_base == NULL) + ABORT("Bad stack base in GC_register_my_thread"); +} + /* This may be called from DllMain, and hence operates under unusual */ /* constraints. In particular, it must be lock-free if */ /* GC_win32_dll_threads is set. Always called from the thread being */ @@ -456,10 +467,7 @@ STATIC GC_thread GC_register_my_thread_inner(const struct GC_stack_base *sb, } # endif me -> last_stack_min = ADDR_LIMIT; - me -> stack_base = sb -> mem_base; -# ifdef IA64 - me -> backing_store_end = sb -> reg_base; -# endif + GC_record_stack_base(me, sb); /* Up until this point, GC_push_all_stacks considers this thread */ /* invalid. */ /* Up until this point, this entry is viewed as reserved but invalid */ @@ -468,8 +476,6 @@ STATIC GC_thread GC_register_my_thread_inner(const struct GC_stack_base *sb, # if defined(THREAD_LOCAL_ALLOC) GC_init_thread_local((GC_tlfs)(&(me->tlfs))); # endif - if (me -> stack_base == NULL) - ABORT("Bad stack base in GC_register_my_thread_inner"); # ifndef GC_NO_THREADS_DISCOVERY if (GC_win32_dll_threads) { if (GC_please_stop) { @@ -707,6 +713,7 @@ GC_API void GC_CALL GC_allow_register_threads(void) GC_API int GC_CALL GC_register_my_thread(const struct GC_stack_base *sb) { + GC_thread me; DWORD thread_id = GetCurrentThreadId(); DCL_LOCK_STATE; @@ -715,11 +722,27 @@ GC_API int GC_CALL GC_register_my_thread(const struct GC_stack_base *sb) /* We lock here, since we want to wait for an ongoing GC. */ LOCK(); - if (0 == GC_lookup_thread_inner(thread_id)) { + me = GC_lookup_thread_inner(thread_id); + if (me == 0) { GC_register_my_thread_inner(sb, thread_id); +# ifdef GC_PTHREADS + me -> flags |= DETACHED; +# endif UNLOCK(); return GC_SUCCESS; - } else { + } else +# ifdef GC_PTHREADS + /* else */ if ((me -> flags & FINISHED) != 0) { + GC_record_stack_base(me, sb); + me -> flags = (me -> flags & ~FINISHED) | DETACHED; +# ifdef THREAD_LOCAL_ALLOC + GC_init_thread_local((GC_tlfs)(&me->tlfs)); +# endif + UNLOCK(); + return GC_SUCCESS; + } else +# endif + /* else */ { UNLOCK(); return GC_DUPLICATE; } |