diff --git a/gc.c b/gc.c index 1ef1f329..a36e1245 100644 --- a/gc.c +++ b/gc.c @@ -438,10 +438,10 @@ PHASE 2 - multi-threaded mutator (IE, more than one stack thread): // // Note: will need to use atomics and/or locking to access any // variables shared between threads -static int gc_color_mark = 0; // Black -static const int gc_color_grey = 1; // TODO: appears unused, clean up -static int gc_color_clear = 2; // White -static const int gc_color_blue = 3; +static int gc_color_mark = 0; // Black, is swapped during GC +//static const int gc_color_grey = 1; // TODO: appears unused, clean up +static int gc_color_clear = 2; // White, is swapped during GC +// unfortunately this had to be split up; const colors are located in types.h static int gc_status_col; static int gc_stage; @@ -502,20 +502,21 @@ void gc_mark_gray(gc_thread_data *thd, object obj) void gc_collector_trace() { int clean = 0; - while (!clean) { - clean = 1; - } - TODO: need a list of mutators. - could keep a buffer or linked list of them. a list may be more efficient - also need to consider how to map thread back to its gc_thread_data, - which we will need during GC (cooperate). maybe use a (platform-specific) - call like below to get a unique ID for the thread, and then use a - hashtable to get the thread info. how often will we be accessing this data? - seems we will need to be able to access it from 2 places: - - from mutator (can compute thread id here) - - from collector (need to be able to iterate across all mutators) - #include - printf("tid = %d\n", syscall(SYS_gettid)); +// while (!clean) { +// clean = 1; +// } +// TODO: need a list of mutators. +// could keep a buffer or linked list of them. a list may be more efficient +// also need to consider how to map thread back to its gc_thread_data, +// which we will need during GC (cooperate). maybe use a (platform-specific) +// call like below to get a unique ID for the thread, and then use a +// hashtable to get the thread info. how often will we be accessing this data? +// seems we will need to be able to access it from 2 places: +// - from mutator (can compute thread id here) +// - from collector (need to be able to iterate across all mutators) +// #include +// printf("tid = %d\n", syscall(SYS_gettid)); + // note - can atomic operations be used for last read/write, to prevent // coarser-grained synchronization there? // TODO: diff --git a/include/cyclone/types.h b/include/cyclone/types.h index 5056ce9e..85c5517d 100644 --- a/include/cyclone/types.h +++ b/include/cyclone/types.h @@ -88,6 +88,12 @@ typedef enum { STAGE_CLEAR_OR_MARKING , STAGE_RESTING } gc_stage_type; +// Constant colors are defined here. +// The mark/clear colors are defined in the gc module because +// the collector swaps their values as an optimization. +const int gc_color_blue = 3; // Unallocate memory +const int gc_color_red = 4; // Memory on the stack + /* Utility functions */ void **vpbuffer_realloc(void **buf, int *len); void **vpbuffer_add(void **buf, int *len, int i, void *obj); @@ -212,7 +218,7 @@ typedef void (*function_type_va)(int, object, object, object, ...); /* Define C-variable integration type */ typedef struct {gc_header_type hdr; tag_type tag; object *pvar;} cvar_type; typedef cvar_type *cvar; -#define make_cvar(n,v) cvar_type n; n.tag = cvar_tag; n.pvar = v; +#define make_cvar(n,v) cvar_type n; n.hdr.mark = gc_color_red; n.tag = cvar_tag; n.pvar = v; /* Define boolean type. */ typedef struct {gc_header_type hdr; const tag_type tag; const char *pname;} boolean_type; @@ -233,9 +239,9 @@ static object quote_##name = nil; /* Define numeric types */ typedef struct {gc_header_type hdr; tag_type tag; int value;} integer_type; -#define make_int(n,v) integer_type n; n.tag = integer_tag; n.value = v; +#define make_int(n,v) integer_type n; n.hdr.mark = gc_color_red; n.tag = integer_tag; n.value = v; typedef struct {gc_header_type hdr; tag_type tag; double value;} double_type; -#define make_double(n,v) double_type n; n.tag = double_tag; n.value = v; +#define make_double(n,v) double_type n; n.hdr.mark = gc_color_red; n.tag = double_tag; n.value = v; #define integer_value(x) (((integer_type *) x)->value) #define double_value(x) (((double_type *) x)->value) @@ -246,30 +252,18 @@ typedef struct {gc_header_type hdr; tag_type tag; int len; char *str;} string_ty //// all functions that allocate strings, the GC, cgen, and maybe more. //// Because these strings are (at least for now) allocaed on the stack. #define make_string(cs, s) string_type cs; \ -{ int len = strlen(s); cs.tag = string_tag; cs.len = len; \ +{ int len = strlen(s); cs.tag = string_tag; cs.len = len; cs.hdr.mark = gc_color_red; \ cs.str = alloca(sizeof(char) * (len + 1)); \ memcpy(cs.str, s, len + 1);} -#define make_string_with_len(cs, s, length) string_type cs; \ +#define make_string_with_len(cs, s, length) string_type cs; cs.hdr.mark = gc_color_red; \ { int len = length; \ cs.tag = string_tag; cs.len = len; \ cs.str = alloca(sizeof(char) * (len + 1)); \ memcpy(cs.str, s, len); \ cs.str[len] = '\0';} -#define make_string_noalloc(cs, s, length) string_type cs; \ +#define make_string_noalloc(cs, s, length) string_type cs; cs.hdr.mark = gc_color_red; \ { cs.tag = string_tag; cs.len = length; \ cs.str = s; } -// TODO: all of the dhalloc below needs to go away... -//#define make_string(cv,s) string_type cv; cv.tag = string_tag; \ -//{ int len = strlen(s); cv.str = dhallocp; \ -// if ((dhallocp + len + 1) >= dhbottom + global_heap_size) { \ -// printf("Fatal error: data heap overflow\n"); exit(1); } \ -// memcpy(dhallocp, s, len + 1); dhallocp += len + 1; } -//#define make_stringn(cv,s,len) string_type cv; cv.tag = string_tag; \ -//{ cv.str = dhallocp; \ -// if ((dhallocp + len + 1) >= dhbottom + global_heap_size) { \ -// printf("Fatal error: data heap overflow\n"); exit(1); } \ -// memcpy(dhallocp, s, len); dhallocp += len; \ -// *dhallocp = '\0'; dhallocp += 1;} #define string_len(x) (((string_type *) x)->len) #define string_str(x) (((string_type *) x)->str) @@ -281,14 +275,14 @@ typedef struct {gc_header_type hdr; tag_type tag; int len; char *str;} string_ty // TODO: a simple wrapper around FILE may not be good enough long-term // TODO: how exactly mode will be used. need to know r/w, bin/txt typedef struct {gc_header_type hdr; tag_type tag; FILE *fp; int mode;} port_type; -#define make_port(p,f,m) port_type p; p.tag = port_tag; p.fp = f; p.mode = m; +#define make_port(p,f,m) port_type p; p.hdr.mark = gc_color_red; p.tag = port_tag; p.fp = f; p.mode = m; /* Vector type */ typedef struct {gc_header_type hdr; tag_type tag; int num_elt; object *elts;} vector_type; typedef vector_type *vector; -#define make_empty_vector(v) vector_type v; v.tag = vector_tag; v.num_elt = 0; v.elts = NULL; +#define make_empty_vector(v) vector_type v; v.hdr.mark = gc_color_red; v.tag = vector_tag; v.num_elt = 0; v.elts = NULL; /* Define cons type. */ @@ -348,15 +342,15 @@ typedef closureN_type *closureN; typedef closure0_type *closure; typedef closure0_type *macro; -#define mmacro(c,f) macro_type c; c.tag = macro_tag; c.fn = f; c.num_args = -1; -#define mclosure0(c,f) closure0_type c; c.tag = closure0_tag; c.fn = f; c.num_args = -1; -#define mclosure1(c,f,a) closure1_type c; c.tag = closure1_tag; \ +#define mmacro(c,f) macro_type c; c.hdr.mark = gc_color_red; c.tag = macro_tag; c.fn = f; c.num_args = -1; +#define mclosure0(c,f) closure0_type c; c.hdr.mark = gc_color_red; c.tag = closure0_tag; c.fn = f; c.num_args = -1; +#define mclosure1(c,f,a) closure1_type c; c.hdr.mark = gc_color_red; c.tag = closure1_tag; \ c.fn = f; c.num_args = -1; c.elt1 = a; -#define mclosure2(c,f,a1,a2) closure2_type c; c.tag = closure2_tag; \ +#define mclosure2(c,f,a1,a2) closure2_type c; c.hdr.mark = gc_color_red; c.tag = closure2_tag; \ c.fn = f; c.num_args = -1; c.elt1 = a1; c.elt2 = a2; -#define mclosure3(c,f,a1,a2,a3) closure3_type c; c.tag = closure3_tag; \ +#define mclosure3(c,f,a1,a2,a3) closure3_type c; c.hdr.mark = gc_color_red; c.tag = closure3_tag; \ c.fn = f; c.num_args = -1; c.elt1 = a1; c.elt2 = a2; c.elt3 = a3; -#define mclosure4(c,f,a1,a2,a3,a4) closure4_type c; c.tag = closure4_tag; \ +#define mclosure4(c,f,a1,a2,a3,a4) closure4_type c; c.hdr.mark = gc_color_red; c.tag = closure4_tag; \ c.fn = f; c.num_args = -1; c.elt1 = a1; c.elt2 = a2; c.elt3 = a3; c.elt4 = a4; #define mlist1(e1) (mcons(e1,nil)) diff --git a/scheme/cyclone/cgen.sld b/scheme/cyclone/cgen.sld index b1d7be0d..2689cec6 100644 --- a/scheme/cyclone/cgen.sld +++ b/scheme/cyclone/cgen.sld @@ -996,6 +996,7 @@ (create-nclosure (lambda () (string-append "closureN_type " cv-name ";\n" + cv-name ".hdr.mark = gc_color_red;\n " cv-name ".tag = closureN_tag;\n " cv-name ".fn = (function_type)__lambda_" (number->string lid) ";\n" cv-name ".num_args = " (number->string (compute-num-args lam)) ";\n"