diff --git a/racket/src/racket/gc2/newgc.c b/racket/src/racket/gc2/newgc.c index 4ea848be4e..9b339e946c 100644 --- a/racket/src/racket/gc2/newgc.c +++ b/racket/src/racket/gc2/newgc.c @@ -780,6 +780,9 @@ static void NewGC_initialize(NewGC *newgc, NewGC *inheritgc, NewGC *parentgc) { #ifdef MZ_USE_PLACES mzrt_mutex_create(&newgc->child_total_lock); #endif +#ifdef USE_MUTEX_FOR_MODIFIED_PAGES + mzrt_mutex_create(&newgc->modified_pages_lock); +#endif } /* NOTE This method sets the constructed GC as the new Thread Specific GC. */ @@ -1089,11 +1092,17 @@ static int designate_modified_gc(NewGC *gc, void *p) } if (page) { +#ifdef USE_MUTEX_FOR_MODIFIED_PAGES + mzrt_mutex_lock(gc->modified_pages_lock); +#endif page->mprotected = 0; mmu_write_unprotect_page(gc->mmu, page->addr, real_page_size(page), page_mmu_type(page), &page->mmu_src_block); if (!page->back_pointers) set_has_back_pointers(gc, page); gc->modified_unprotects++; +#ifdef USE_MUTEX_FOR_MODIFIED_PAGES + mzrt_mutex_unlock(gc->modified_pages_lock); +#endif errno = saved_errno; return 1; } else { diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index 080adae925..3346006b60 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -53,6 +53,10 @@ enum { AGE_GEN_INC = 4 /* used for naming a finalizer set */ }; +#if defined(MZ_USE_FUTURES) && !defined(OS_X) +# define USE_MUTEX_FOR_MODIFIED_PAGES +#endif + typedef struct mpage { struct mpage *next; struct mpage *prev; @@ -396,7 +400,11 @@ typedef struct NewGC { uintptr_t child_gc_cumulative; uintptr_t child_gc_max; - uintptr_t place_memory_limit; /* set to propagate a custodian limit from a parent place */ + uintptr_t place_memory_limit; /* set to propagate a custodian limit from a parent place */ + +#ifdef USE_MUTEX_FOR_MODIFIED_PAGES + mzrt_mutex *modified_pages_lock; +#endif #if MZ_GC_BACKTRACE void *bt_source; diff --git a/racket/src/racket/gc2/vm_osx.c b/racket/src/racket/gc2/vm_osx.c index cad91620b6..43eb39f75a 100644 --- a/racket/src/racket/gc2/vm_osx.c +++ b/racket/src/racket/gc2/vm_osx.c @@ -427,6 +427,10 @@ static void macosx_init_exception_handler(int isMASTERGC) { kern_return_t retval; + /* Note: the `designate_modified` function relies on the fact that + all exceptions (at least within a place) go through the same + handler thread, so it can skip the lock on modified pages. */ + if (!isMASTERGC) { GC_attach_current_thread_exceptions_to_handler(); return;