diff --git a/gc.c b/gc.c index 5b479560..a15b0f51 100644 --- a/gc.c +++ b/gc.c @@ -976,13 +976,13 @@ void gc_collector_trace() // TODO: ideally, want to use a lock-free data structure to prevent // having to use a mutex here. see corresponding code in gc_mark_gray -TODO: I think this locking is too coarse. observing immediate failures with the recent change to g_mark_gray locking and -wonder if the problem is that this locking will prevent a batch of changes from being seen. -you know, do we really need locking here? the last read/write can be made atomic, and any reads/writes to mark buffer can -be made atomic as well. I think we may need a dirty flag to let the collector know something is happening when the mark buffer -needs to be resized, but other than that it this good enough? -on the other hand, a central issue with this collector is when can we be sure that we are existing tracing at the right time, and -not too early? because an early exit here will surely mean that objects are incorrectly freed +//TODO: I think this locking is too coarse. observing immediate failures with the recent change to g_mark_gray locking and +//wonder if the problem is that this locking will prevent a batch of changes from being seen. +//you know, do we really need locking here? the last read/write can be made atomic, and any reads/writes to mark buffer can +//be made atomic as well. I think we may need a dirty flag to let the collector know something is happening when the mark buffer +//needs to be resized, but other than that it this good enough? +//on the other hand, a central issue with this collector is when can we be sure that we are existing tracing at the right time, and +//not too early? because an early exit here will surely mean that objects are incorrectly freed pthread_mutex_lock(&(m->lock)); while (m->last_read < m->last_write) { clean = 0; @@ -996,6 +996,18 @@ not too early? because an early exit here will surely mean that objects are inco (m->last_read)++; // Inc here to prevent off-by-one error } pthread_mutex_unlock(&(m->lock)); + + // Try checking the condition once more after giving the + // mutator a chance to respond, to prevent exiting early. + // This is experimental, not sure if it is necessary + if (clean) { + pthread_mutex_lock(&(m->lock)); + if (m->last_read < m->last_write) { + printf("JAE DEBUG - might have exited trace early\n"); + clean = 0; + } + pthread_mutex_unlock(&(m->lock)); + } } } }