Re-enable cooperation code

This commit is contained in:
Justin Ethier 2015-12-24 01:32:40 -05:00
parent b31c6181c8
commit 43ff5c5454

114
gc.c
View file

@ -1167,32 +1167,30 @@ void gc_wait_handshake()
pthread_mutex_unlock(&(m->lock)); pthread_mutex_unlock(&(m->lock));
}else if (statusc == STATUS_SYNC2) { }else if (statusc == STATUS_SYNC2) {
ATOMIC_SET_IF_EQ(&(m->gc_status), statusc, statusm); ATOMIC_SET_IF_EQ(&(m->gc_status), statusc, statusm);
} else if (statusc == STATUS_ASYNC) {
printf("DEBUG - is mutator still blocked?\n");
// Check again, if thread is still blocked we need to cooperate
if (ATOMIC_SET_IF_EQ(&(m->thread_state),
CYC_THREAD_STATE_BLOCKED,
CYC_THREAD_STATE_BLOCKED_COOPERATING)) {
printf("DEBUG - update mutator GC status\n");
ATOMIC_SET_IF_EQ(&(m->gc_status), statusc, statusm);
pthread_mutex_lock(&(m->lock));
printf("DEBUG - collector is cooperating for blocked mutator\n");
buf_len = gc_minor(m, m->stack_limit, m->stack_start, m->gc_cont, NULL, 0);
// Mark thread "roots", based on code from mutator's cooperator
gc_mark_gray(m, m->gc_cont);
//for (i = 0; i < m->gc_num_args; i++) {
// gc_mark_gray(m, m->gc_args[i]);
//}
// Also, mark everything the collector moved to the heap
for (i = 0; i < buf_len; i++) {
gc_mark_gray(m, m->moveBuf[i]);
}
m->gc_alloc_color = ATOMIC_GET(&gc_color_mark);
pthread_mutex_unlock(&(m->lock));
}
} }
// TODO: allow collector to cooperate on behalf of a mutator for the async phase
// else if (statusc == STATUS_ASYNC) {
//printf("DEBUG - is mutator still blocked?\n");
// // Check again, if thread is still blocked we need to cooperate
// if (ATOMIC_SET_IF_EQ(&(m->thread_state),
// CYC_THREAD_STATE_BLOCKED,
// CYC_THREAD_STATE_BLOCKED_COOPERATING)) {
//printf("DEBUG - update mutator GC status\n");
// ATOMIC_SET_IF_EQ(&(m->gc_status), statusc, statusm);
// pthread_mutex_lock(&(m->lock));
//printf("DEBUG - collector is cooperating for blocked mutator\n");
// buf_len = gc_minor(m, m->stack_limit, m->stack_start, m->gc_cont, NULL, 0);
// // Mark thread "roots", based on code from mutator's cooperator
// gc_mark_gray(m, m->gc_cont);
// //for (i = 0; i < m->gc_num_args; i++) {
// // gc_mark_gray(m, m->gc_args[i]);
// //}
// // Also, mark everything the collector moved to the heap
// for (i = 0; i < buf_len; i++) {
// gc_mark_gray(m, m->moveBuf[i]);
// }
// m->gc_alloc_color = ATOMIC_GET(&gc_color_mark);
// pthread_mutex_unlock(&(m->lock));
// }
// }
} else if (thread_status == CYC_THREAD_STATE_TERMINATED) { } else if (thread_status == CYC_THREAD_STATE_TERMINATED) {
// Thread is no longer running // Thread is no longer running
break; break;
@ -1382,49 +1380,49 @@ void gc_thread_data_free(gc_thread_data *thd)
void gc_mutator_thread_blocked(gc_thread_data *thd, object cont) void gc_mutator_thread_blocked(gc_thread_data *thd, object cont)
{ {
ATOMIC_SET_IF_EQ(&(thd->thread_state), if(!ATOMIC_SET_IF_EQ(&(thd->thread_state),
CYC_THREAD_STATE_RUNNABLE, CYC_THREAD_STATE_RUNNABLE,
CYC_THREAD_STATE_BLOCKED); CYC_THREAD_STATE_BLOCKED)){
fprintf(stderr, "Unable to change thread from runnable to blocked. status = %d\n", thd->thread_state);
exit(1);
}
thd->gc_cont = cont; thd->gc_cont = cont;
thd->gc_num_args = 0; // Will be set later, after collection thd->gc_num_args = 0; // Will be set later, after collection
} }
void gc_mutator_thread_runnable(gc_thread_data *thd, object result) void gc_mutator_thread_runnable(gc_thread_data *thd, object result)
{ {
ATOMIC_SET_IF_EQ(&(thd->thread_state), // Transition from blocked back to runnable using CAS.
// If we are unable to transition back, assume collector
// has cooperated on behalf of this mutator thread.
if (!ATOMIC_SET_IF_EQ(&(thd->thread_state),
CYC_THREAD_STATE_BLOCKED, CYC_THREAD_STATE_BLOCKED,
CYC_THREAD_STATE_RUNNABLE); CYC_THREAD_STATE_RUNNABLE)){
// // Transition from blocked back to runnable using CAS. printf("DEBUG - Collector cooperated, wait for it to finish. status is %d\n", thd->thread_state);
// // If we are unable to transition back, assume collector // wait for the collector to finish
// // has cooperated on behalf of this mutator thread. pthread_mutex_lock(&(thd->lock));
// if (!ATOMIC_SET_IF_EQ(&(thd->thread_state), pthread_mutex_unlock(&(thd->lock));
// CYC_THREAD_STATE_BLOCKED, // update thread status
// CYC_THREAD_STATE_RUNNABLE)){ while(!ATOMIC_SET_IF_EQ(&(thd->thread_state),
//printf("DEBUG - Collector cooperated, wait for it to finish\n"); CYC_THREAD_STATE_BLOCKED_COOPERATING,
// // wait for the collector to finish CYC_THREAD_STATE_RUNNABLE)){}
// pthread_mutex_lock(&(thd->lock)); // transport result to heap, if necessary (IE, is not a value type)
// pthread_mutex_unlock(&(thd->lock)); if (is_object_type(result)) {
// // update thread status // TODO: need to move object to heap
// while(!ATOMIC_SET_IF_EQ(&(thd->thread_state), // TODO: also, then need to gc_mark_gray heap obj
// CYC_THREAD_STATE_BLOCKED_COOPERATING, fprintf(stderr, "Unhandled object type result, TODO: implement\n");
// CYC_THREAD_STATE_RUNNABLE)){} exit(1);
// // transport result to heap, if necessary (IE, is not a value type) }
// if (is_object_type(result)) { // Setup value to send to continuation
// // TODO: need to move object to heap thd->gc_args[0] = result;
// // TODO: also, then need to gc_mark_gray heap obj thd->gc_num_args = 1;
// fprintf(stderr, "Unhandled object type result, TODO: implement\n"); // Whoa.
// exit(1); printf("DEBUG - Call into gc_cont after collector coop\n");
// } longjmp(*(thd->jmp_start), 1);
// // Setup value to send to continuation } else {
// thd->gc_args[0] = result;
// thd->gc_num_args = 1;
// // Whoa.
//printf("DEBUG - Call into gc_cont after collector coop\n");
// longjmp(*(thd->jmp_start), 1);
// } else {
// Collector didn't do anything; make a normal continuation call // Collector didn't do anything; make a normal continuation call
(((closure)(thd->gc_cont))->fn)(thd, 1, thd->gc_cont, result); (((closure)(thd->gc_cont))->fn)(thd, 1, thd->gc_cont, result);
// } }
} }
//// Unit testing: //// Unit testing: