summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2022-10-13 23:49:01 +0300
committerIvan Maidanski <ivmai@mail.ru>2022-11-15 11:04:00 +0300
commite50e7b3272bfa861276551d42ec1618b6b3bdc8d (patch)
tree047d4e0ef1baef1b023cf275ad2501daaa930f82
parente3c69a498cbaf1306e385b28c0d1e6c7bee6099d (diff)
downloadbdwgc-e50e7b3272bfa861276551d42ec1618b6b3bdc8d.tar.gz
Fix double initialization of main thread local free lists on Win32
(a cherry-pick of commit 4b101ee06 from 'release-8_2') * win32_threads.c [THREAD_LOCAL_ALLOC] (GC_register_my_thread_inner): Update comment; do not call GC_init_thread_local(). * win32_threads.c [THREAD_LOCAL_ALLOC] (GC_register_my_thread): Call GC_init_thread_local() both after GC_register_my_thread_inner() and GC_record_stack_base() calls (in case of return GC_SUCCESS). * win32_threads.c [GC_PTHREADS && THREAD_LOCAL_ALLOC] (GC_pthread_start_inner): Call GC_init_thread_local().
-rw-r--r--win32_threads.c24
1 files changed, 12 insertions, 12 deletions
diff --git a/win32_threads.c b/win32_threads.c
index 73f1e7a9..36db9298 100644
--- a/win32_threads.c
+++ b/win32_threads.c
@@ -402,6 +402,7 @@ GC_INLINE void GC_record_stack_base(GC_vthread me,
/* GC_win32_dll_threads is set. Always called from the thread being */
/* added. If GC_win32_dll_threads is not set, we already hold the */
/* allocation lock except possibly during single-threaded startup code. */
+/* Does not initialize thread local free lists. */
STATIC GC_thread GC_register_my_thread_inner(const struct GC_stack_base *sb,
DWORD thread_id)
{
@@ -493,9 +494,6 @@ STATIC GC_thread GC_register_my_thread_inner(const struct GC_stack_base *sb,
/* Up until this point, this entry is viewed as reserved but invalid */
/* by GC_delete_thread. */
me -> id = thread_id;
-# if defined(THREAD_LOCAL_ALLOC)
- GC_init_thread_local((GC_tlfs)(&(me->tlfs)));
-# endif
# ifndef GC_NO_THREADS_DISCOVERY
if (GC_win32_dll_threads) {
if (GC_please_stop) {
@@ -769,32 +767,31 @@ GC_API int GC_CALL GC_register_my_thread(const struct GC_stack_base *sb)
LOCK();
me = GC_lookup_thread_inner(thread_id);
if (me == 0) {
+ me = GC_register_my_thread_inner(sb, thread_id);
# ifdef GC_PTHREADS
- me = GC_register_my_thread_inner(sb, thread_id);
me -> flags |= DETACHED;
/* Treat as detached, since we do not need to worry about */
/* pointer results. */
# else
- GC_register_my_thread_inner(sb, thread_id);
+ (void)me;
# endif
- UNLOCK();
- return GC_SUCCESS;
} else
# ifdef GC_PTHREADS
/* else */ if ((me -> flags & FINISHED) != 0) {
GC_record_stack_base(me, sb);
me -> flags &= ~FINISHED; /* but not 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;
}
+
+# ifdef THREAD_LOCAL_ALLOC
+ GC_init_thread_local(&me->tlfs);
+# endif
+ UNLOCK();
+ return GC_SUCCESS;
}
/* Similar to that in pthread_support.c. */
@@ -2786,6 +2783,9 @@ GC_INNER void GC_thr_init(void)
SET_PTHREAD_MAP_CACHE(pthread_id, thread_id);
me -> pthread_id = pthread_id;
if (si->detached) me -> flags |= DETACHED;
+# ifdef THREAD_LOCAL_ALLOC
+ GC_init_thread_local(&me->tlfs);
+# endif
UNLOCK();
start = si -> start_routine;