From c59f72f101354534edd12c4f845ee676fb7f7a05 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 2 May 2020 08:43:18 -0600 Subject: [PATCH] bc: reserve GC parking spaces for place-main thread Don't try to park values when allocating a weak box or pair in a future thread, since that creates a race on the parking spaces. A future thread can't run a GC, so it's doesn't need to park. Touching a future in a future allocates a weak box, so this bug could have been responsible for many crahses. Related to #3145 --- racket/src/racket/gc2/newgc.c | 18 +++++++++++------- racket/src/racket/gc2/weak.c | 22 +++++++++++++--------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 0ff801a367..4ea848be4e 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -1744,14 +1744,18 @@ void *GC_malloc_pair(void *car, void *cdr) if (TAKE_SLOW_PATH() || OVERFLOWS_GEN0(newptr)) { NewGC *gc = GC_get_GC(); - CHECK_PARK_UNUSED(gc); - gc->park[0] = car; - gc->park[1] = cdr; + if (!GC_gen0_alloc_only) { + CHECK_PARK_UNUSED(gc); + gc->park[0] = car; + gc->park[1] = cdr; + } pair = allocate(sizeof(Scheme_Simple_Object), PAGE_PAIR); - car = gc->park[0]; - cdr = gc->park[1]; - gc->park[0] = NULL; - gc->park[1] = NULL; + if (!GC_gen0_alloc_only) { + car = gc->park[0]; + cdr = gc->park[1]; + gc->park[0] = NULL; + gc->park[1] = NULL; + } /* Future-local allocation can fail: */ if (!pair) return NULL; diff --git a/racket/src/racket/gc2/weak.c b/racket/src/racket/gc2/weak.c index d85fba66ca..8f360e5d3e 100644 --- a/racket/src/racket/gc2/weak.c +++ b/racket/src/racket/gc2/weak.c @@ -113,7 +113,7 @@ void *GC_malloc_weak_array(size_t size_in_bytes, void *replace_val) GCTYPE *gc = GC_get_GC(); GC_Weak_Array *w; - /* Allcation might trigger GC, so we use park: */ + /* Allocation might trigger GC, so we use park: */ CHECK_PARK_UNUSED(gc); gc->park[0] = replace_val; @@ -303,20 +303,24 @@ void *GC_malloc_weak_box(void *p, void **secondary, int soffset, int is_late) GCTYPE *gc = GC_get_GC(); GC_Weak_Box *w; - /* Allcation might trigger GC, so we use park: */ - CHECK_PARK_UNUSED(gc); - gc->park[0] = p; - gc->park[1] = secondary; + if (!GC_gen0_alloc_only) { + /* Allcation might trigger GC, so we use park: */ + CHECK_PARK_UNUSED(gc); + gc->park[0] = p; + gc->park[1] = secondary; + } w = (GC_Weak_Box *)GC_malloc_one_tagged(sizeof(GC_Weak_Box)); /* Future-local allocation may fail: */ if (!w) return NULL; - p = gc->park[0]; - secondary = (void **)gc->park[1]; - gc->park[0] = NULL; - gc->park[1] = NULL; + if (!GC_gen0_alloc_only) { + p = gc->park[0]; + secondary = (void **)gc->park[1]; + gc->park[0] = NULL; + gc->park[1] = NULL; + } w->type = gc->weak_box_tag; w->val = p;