mirror of
https://github.com/justinethier/cyclone.git
synced 2025-07-14 00:07:36 +02:00
Use atomics to access thd->gc_status
This commit is contained in:
parent
9a9b3cc640
commit
ec8821b9ef
1 changed files with 18 additions and 9 deletions
27
gc.c
27
gc.c
|
@ -771,7 +771,7 @@ void gc_mut_update(gc_thread_data *thd, object old_obj, object value)
|
||||||
{
|
{
|
||||||
int status = ATOMIC_GET(&gc_status_col),
|
int status = ATOMIC_GET(&gc_status_col),
|
||||||
stage = ATOMIC_GET(&gc_stage);
|
stage = ATOMIC_GET(&gc_stage);
|
||||||
if (thd->gc_status != STATUS_ASYNC) {
|
if (ATOMIC_GET(&(thd->gc_status)) != STATUS_ASYNC) {
|
||||||
//fprintf(stderr, "DEBUG - GC sync marking heap obj %p ", old_obj);
|
//fprintf(stderr, "DEBUG - GC sync marking heap obj %p ", old_obj);
|
||||||
//Cyc_display(old_obj, stderr);
|
//Cyc_display(old_obj, stderr);
|
||||||
//fprintf(stderr, " and new value %p ", value);
|
//fprintf(stderr, " and new value %p ", value);
|
||||||
|
@ -836,7 +836,7 @@ void gc_mut_update(gc_thread_data *thd, object old_obj, object value)
|
||||||
// TODO: still need to handle case where a mutator is blocked
|
// TODO: still need to handle case where a mutator is blocked
|
||||||
void gc_mut_cooperate(gc_thread_data *thd, int buf_len)
|
void gc_mut_cooperate(gc_thread_data *thd, int buf_len)
|
||||||
{
|
{
|
||||||
int i, status;
|
int i, status_c, status_m;
|
||||||
#if GC_DEBUG_VERBOSE
|
#if GC_DEBUG_VERBOSE
|
||||||
int debug_print = 0;
|
int debug_print = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -847,9 +847,16 @@ void gc_mut_cooperate(gc_thread_data *thd, int buf_len)
|
||||||
thd->pending_writes = 0;
|
thd->pending_writes = 0;
|
||||||
pthread_mutex_unlock(&(thd->lock));
|
pthread_mutex_unlock(&(thd->lock));
|
||||||
|
|
||||||
status = ATOMIC_GET(&gc_status_col);
|
// TODO: I think below is thread safe, but this code is tricky.
|
||||||
if (thd->gc_status != status) {
|
// worst case should be that some work is done twice if there is
|
||||||
if (thd->gc_status == STATUS_ASYNC) {
|
// a race condition
|
||||||
|
//
|
||||||
|
// TODO: should use an atomic comparison here
|
||||||
|
status_c = ATOMIC_GET(&gc_status_col);
|
||||||
|
status_m = ATOMIC_GET(&(thd->gc_status));
|
||||||
|
if (status_m != status_c) {
|
||||||
|
ATOMIC_SET_IF_EQ(&(thd->gc_status), status_m, status_c);
|
||||||
|
if (status_m == STATUS_ASYNC) {
|
||||||
// Async is done, so clean up old mark data from the last collection
|
// Async is done, so clean up old mark data from the last collection
|
||||||
pthread_mutex_lock(&(thd->lock));
|
pthread_mutex_lock(&(thd->lock));
|
||||||
thd->last_write = 0;
|
thd->last_write = 0;
|
||||||
|
@ -857,7 +864,7 @@ void gc_mut_cooperate(gc_thread_data *thd, int buf_len)
|
||||||
thd->pending_writes = 0;
|
thd->pending_writes = 0;
|
||||||
pthread_mutex_unlock(&(thd->lock));
|
pthread_mutex_unlock(&(thd->lock));
|
||||||
}
|
}
|
||||||
else if (thd->gc_status == STATUS_SYNC2) {
|
else if (status_m == STATUS_SYNC2) {
|
||||||
#if GC_DEBUG_VERBOSE
|
#if GC_DEBUG_VERBOSE
|
||||||
debug_print = 1;
|
debug_print = 1;
|
||||||
#endif
|
#endif
|
||||||
|
@ -876,7 +883,6 @@ void gc_mut_cooperate(gc_thread_data *thd, int buf_len)
|
||||||
pthread_mutex_unlock(&(thd->lock));
|
pthread_mutex_unlock(&(thd->lock));
|
||||||
thd->gc_alloc_color = ATOMIC_GET(&gc_color_mark);
|
thd->gc_alloc_color = ATOMIC_GET(&gc_color_mark);
|
||||||
}
|
}
|
||||||
thd->gc_status = status;
|
|
||||||
}
|
}
|
||||||
#if GC_DEBUG_VERBOSE
|
#if GC_DEBUG_VERBOSE
|
||||||
if (debug_print) {
|
if (debug_print) {
|
||||||
|
@ -1141,15 +1147,18 @@ void gc_wait_handshake()
|
||||||
|
|
||||||
CK_ARRAY_FOREACH(&Cyc_mutators, &iterator, &m) {
|
CK_ARRAY_FOREACH(&Cyc_mutators, &iterator, &m) {
|
||||||
while (1) {
|
while (1) {
|
||||||
|
// TODO: use an atomic comparison
|
||||||
statusc = ATOMIC_GET(&gc_status_col);
|
statusc = ATOMIC_GET(&gc_status_col);
|
||||||
statusm = ATOMIC_GET(&(m->gc_status));
|
statusm = ATOMIC_GET(&(m->gc_status));
|
||||||
thread_status = ATOMIC_GET(&(m->thread_state));
|
|
||||||
if (statusc == statusm) {
|
if (statusc == statusm) {
|
||||||
// Handshake succeeded, check next mutator
|
// Handshake succeeded, check next mutator
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thread_status == CYC_THREAD_STATE_TERMINATED) {
|
thread_status = ATOMIC_GET(&(m->thread_state));
|
||||||
|
if (thread_status == CYC_THREAD_STATE_BLOCKED) {
|
||||||
|
// CAS
|
||||||
|
} else if (thread_status == CYC_THREAD_STATE_TERMINATED) {
|
||||||
// Thread is no longer running
|
// Thread is no longer running
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue