Store cont before mutator is blocked

This commit is contained in:
Justin Ethier 2015-12-22 22:19:04 -05:00
parent 309e35c69b
commit 247b09fc88
3 changed files with 12 additions and 11 deletions

5
gc.c
View file

@ -1360,13 +1360,14 @@ void gc_thread_data_free(gc_thread_data *thd)
} }
} }
void gc_set_thread_state_blocked(gc_thread_data *thd) void gc_set_thread_blocked(gc_thread_data *thd, object cont)
{ {
ATOMIC_SET_IF_EQ(&(thd->thread_state), ATOMIC_SET_IF_EQ(&(thd->thread_state),
CYC_THREAD_STATE_RUNNABLE, CYC_THREAD_STATE_RUNNABLE,
CYC_THREAD_STATE_BLOCKED); CYC_THREAD_STATE_BLOCKED);
thd->gc_cont = cont;
} }
void gc_set_thread_state_runnable(gc_thread_data *thd) void gc_set_thread_runnable(gc_thread_data *thd)
{ {
ATOMIC_SET_IF_EQ(&(thd->thread_state), ATOMIC_SET_IF_EQ(&(thd->thread_state),
CYC_THREAD_STATE_BLOCKED, CYC_THREAD_STATE_BLOCKED,

View file

@ -441,8 +441,8 @@ void gc_handshake(gc_status_type s);
void gc_post_handshake(gc_status_type s); void gc_post_handshake(gc_status_type s);
void gc_wait_handshake(); void gc_wait_handshake();
void gc_start_collector(); void gc_start_collector();
void gc_set_thread_state_blocked(gc_thread_data *thd); void gc_set_thread_blocked(gc_thread_data *thd, object cont);
void gc_set_thread_state_runnable(gc_thread_data *thd); void gc_set_thread_runnable(gc_thread_data *thd);
gc_heap *gc_get_heap(); gc_heap *gc_get_heap();
int gc_minor(void *data, object low_limit, object high_limit, closure cont, object *args, int num_args); int gc_minor(void *data, object low_limit, object high_limit, closure cont, object *args, int num_args);

View file

@ -1490,9 +1490,9 @@ object Cyc_io_read_char(void *data, object cont, object port) {
int c; int c;
Cyc_check_port(data, port); Cyc_check_port(data, port);
{ {
gc_set_thread_state_blocked((gc_thread_data *)data); gc_set_thread_blocked((gc_thread_data *)data, cont);
c = fgetc(((port_type *) port)->fp); c = fgetc(((port_type *) port)->fp);
gc_set_thread_state_runnable((gc_thread_data *)data); gc_set_thread_runnable((gc_thread_data *)data);
if (c != EOF) { if (c != EOF) {
return obj_char2obj(c); return obj_char2obj(c);
} }
@ -1506,17 +1506,17 @@ object Cyc_io_read_line(void *data, object cont, object port) {
char buf[1024]; char buf[1024];
int i = 0, c; int i = 0, c;
gc_set_thread_state_blocked((gc_thread_data *)data); gc_set_thread_blocked((gc_thread_data *)data, cont);
while (1) { while (1) {
c = fgetc(stream); c = fgetc(stream);
if (c == EOF && i == 0) { if (c == EOF && i == 0) {
gc_set_thread_state_runnable((gc_thread_data *)data); gc_set_thread_runnable((gc_thread_data *)data);
return_closcall1(data, cont, Cyc_EOF); return_closcall1(data, cont, Cyc_EOF);
} else if (c == EOF || i == 1023 || c == '\n') { } else if (c == EOF || i == 1023 || c == '\n') {
buf[i] = '\0'; buf[i] = '\0';
{ {
make_string(s, buf); make_string(s, buf);
gc_set_thread_state_runnable((gc_thread_data *)data); gc_set_thread_runnable((gc_thread_data *)data);
return_closcall1(data, cont, &s); return_closcall1(data, cont, &s);
} }
} }
@ -1533,10 +1533,10 @@ object Cyc_io_peek_char(void *data, object cont, object port) {
Cyc_check_port(data, port); Cyc_check_port(data, port);
{ {
stream = ((port_type *) port)->fp; stream = ((port_type *) port)->fp;
gc_set_thread_state_blocked((gc_thread_data *)data); gc_set_thread_blocked((gc_thread_data *)data, cont);
c = fgetc(stream); c = fgetc(stream);
ungetc(c, stream); ungetc(c, stream);
gc_set_thread_state_runnable((gc_thread_data *)data); gc_set_thread_runnable((gc_thread_data *)data);
if (c != EOF) { if (c != EOF) {
return obj_char2obj(c); return obj_char2obj(c);
} }