diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2022-12-29 23:09:27 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2022-12-29 23:09:27 +0300 |
commit | b528d5760e1e05c51b341741833a3caba34ea20a (patch) | |
tree | 16a0443d1fba769c06216118b1d1c27981a57ebf /pthread_support.c | |
parent | 0a1667bee7f2c004abda6ecd173cd80bfef8412c (diff) | |
download | bdwgc-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.c | 14 |
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; |