3m: add missing lock in write barrier
When a future triggers a write barrier, a lock is needed to prevent a race between the future thread and other threads in the same place (on most platforms). Thanks to Dominik Pantůček for tracking down this bug.
This commit is contained in:
parent
567fd9e866
commit
fae20b4b89
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue
Block a user