summaryrefslogtreecommitdiff
path: root/pthread_support.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2022-12-29 23:09:27 +0300
committerIvan Maidanski <ivmai@mail.ru>2022-12-29 23:09:27 +0300
commitb528d5760e1e05c51b341741833a3caba34ea20a (patch)
tree16a0443d1fba769c06216118b1d1c27981a57ebf /pthread_support.c
parent0a1667bee7f2c004abda6ecd173cd80bfef8412c (diff)
downloadbdwgc-b528d5760e1e05c51b341741833a3caba34ea20a.tar.gz
Ensure GC_StackContext_Rep object allocated in GC_new_thread is marked
(fix of commit 7eb49a4e6) Issue #362 (bdwgc). The current stack is not scanned until the thread is registered, thus crtn pointer (to a newly allocated GC_StackContext_Rep object) is to be retained in the global data roots for a while (and pushed explicitly if a collection occurs during GC_Thread_Rep object allocation). * pthread_support.c (saved_crtn): New static variable. * pthread_support.c (GC_push_thread_structures): Push saved_crtn symbol. * pthread_support.c (GC_new_thread): Store crtn to saved_crtn before allocation of GC_thread object and set saved_crtn back to null after the allocation; add comment.
Diffstat (limited to 'pthread_support.c')
-rw-r--r--pthread_support.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/pthread_support.c b/pthread_support.c
index ddb15b9a..892f123f 100644
--- a/pthread_support.c
+++ b/pthread_support.c
@@ -609,6 +609,10 @@ GC_INNER GC_thread GC_threads[THREAD_TABLE_SZ] = {0};
static struct GC_StackContext_Rep first_crtn;
static struct GC_Thread_Rep first_thread;
+/* A place to retain a pointer to an allocated object while a thread */
+/* registration is ongoing. Protected by the GC lock. */
+static GC_stack_context_t saved_crtn = NULL;
+
#ifdef GC_ASSERTIONS
GC_INNER GC_bool GC_thr_initialized = FALSE;
#endif
@@ -631,6 +635,7 @@ void GC_push_thread_structures(void)
GC_PUSH_ALL_SYM(first_crtn.backing_store_end);
# endif
GC_PUSH_ALL_SYM(first_thread.crtn);
+ GC_PUSH_ALL_SYM(saved_crtn);
}
# if defined(THREAD_LOCAL_ALLOC) && defined(USE_CUSTOM_SPECIFIC)
GC_PUSH_ALL_SYM(GC_thread_key);
@@ -714,8 +719,17 @@ GC_INNER_WIN32THREAD GC_thread GC_new_thread(thread_id_t id)
crtn = (GC_stack_context_t)GC_INTERNAL_MALLOC(
sizeof(struct GC_StackContext_Rep), NORMAL);
if (EXPECT(NULL == crtn, FALSE)) return NULL;
+
+ /* The current stack is not scanned until the thread is */
+ /* registered, thus crtn pointer is to be retained in the */
+ /* global data roots for a while (and pushed explicitly if */
+ /* a collection occurs here). */
+ GC_ASSERT(NULL == saved_crtn);
+ saved_crtn = crtn;
result = (GC_thread)GC_INTERNAL_MALLOC(sizeof(struct GC_Thread_Rep),
NORMAL);
+ saved_crtn = NULL; /* no more collections till thread is registered */
+
if (EXPECT(NULL == result, FALSE)) {
GC_INTERNAL_FREE(crtn);
return NULL;