diff --git a/gc.c b/gc.c index 42ff0c0a..e73cadcb 100644 --- a/gc.c +++ b/gc.c @@ -836,8 +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 void gc_mut_cooperate(gc_thread_data *thd, int buf_len) { - int i, status = ATOMIC_GET(&gc_status_col), - stage = ATOMIC_GET(&gc_stage); + int i; #if GC_DEBUG_VERBOSE int debug_print = 0; #endif @@ -848,7 +847,8 @@ void gc_mut_cooperate(gc_thread_data *thd, int buf_len) thd->pending_writes = 0; pthread_mutex_unlock(&(thd->lock)); - if (thd->gc_status != status) { + if (thd->gc_status != ATOMIC_GET(&gc_status_col)) { + thd->gc_status = ATOMIC_GET(&gc_status_col); if (thd->gc_status == STATUS_ASYNC) { // Async is done, so clean up old mark data from the last collection pthread_mutex_lock(&(thd->lock)); @@ -876,7 +876,6 @@ void gc_mut_cooperate(gc_thread_data *thd, int buf_len) pthread_mutex_unlock(&(thd->lock)); thd->gc_alloc_color = ATOMIC_GET(&gc_color_mark); } - thd->gc_status = status; } #if GC_DEBUG_VERBOSE if (debug_print) { @@ -893,7 +892,7 @@ void gc_mut_cooperate(gc_thread_data *thd, int buf_len) // Initiate collection cycle if free space is too low. // Threshold is intentially low because we have to go through an // entire handshake/trace/sweep cycle, ideally without growing heap. - if (stage == STAGE_RESTING && + if (ATOMIC_GET(&gc_stage) == STAGE_RESTING && (cached_heap_free_size < (cached_heap_total_size * 0.50))){ #if GC_DEBUG_TRACE fprintf(stdout, "Less than 50%% of the heap is free, initiating collector\n"); @@ -1336,6 +1335,19 @@ void gc_thread_data_free(gc_thread_data *thd) } } +void gc_set_thread_state_blocked(gc_thread_data *thd) +{ + ATOMIC_SET_IF_EQ(&(thd->thread_state), + CYC_THREAD_STATE_RUNNABLE, + CYC_THREAD_STATE_BLOCKED); +} +void gc_set_thread_state_runnable(gc_thread_data *thd) +{ + ATOMIC_SET_IF_EQ(&(thd->thread_state), + CYC_THREAD_STATE_BLOCKED, + CYC_THREAD_STATE_RUNNABLE); +} + //// Unit testing: //int main(int argc, char **argv) { // int a = 1, b = 2, c = 3, i; diff --git a/include/cyclone/types.h b/include/cyclone/types.h index b2c23252..0c2d6bb6 100644 --- a/include/cyclone/types.h +++ b/include/cyclone/types.h @@ -52,6 +52,7 @@ typedef void *object; /* Threading */ typedef enum { CYC_THREAD_STATE_NEW , CYC_THREAD_STATE_RUNNABLE + , CYC_THREAD_STATE_BLOCKED , CYC_THREAD_STATE_TERMINATED } cyc_thread_state_type; @@ -203,6 +204,8 @@ void gc_handshake(gc_status_type s); void gc_post_handshake(gc_status_type s); void gc_wait_handshake(); void gc_start_collector(); +void gc_set_thread_state_blocked(gc_thread_data *thd); +void gc_set_thread_state_runnable(gc_thread_data *thd); gc_heap *gc_get_heap(); /////////////////////////////////////////////