diff --git a/gc.c b/gc.c index cc6532ea..98334da6 100644 --- a/gc.c +++ b/gc.c @@ -333,6 +333,13 @@ char *gc_copy_obj(object dest, char *obj, gc_thread_data *thd) hp->pvar = ((cvar_type *) obj)->pvar; return (char *)hp; } + case mutex_tag: { + mutex_type *hp = dest; + mark(hp) = thd->gc_alloc_color; + type_of(hp) = mutex_tag; + // NOTE: don't copy mutex itself, caller will do that (this is a special case) + return (char *)hp; + } case forward_tag: return (char *)forward(obj); case eof_tag: diff --git a/include/cyclone/runtime.h b/include/cyclone/runtime.h index ae602353..ed3e62f7 100644 --- a/include/cyclone/runtime.h +++ b/include/cyclone/runtime.h @@ -30,6 +30,7 @@ #define Cyc_check_sym(d,obj) Cyc_check_type(d,Cyc_is_symbol, symbol_tag, obj); #define Cyc_check_vec(d,obj) Cyc_check_type(d,Cyc_is_vector, vector_tag, obj); #define Cyc_check_port(d,obj) Cyc_check_type(d,Cyc_is_port, port_tag, obj); +#define Cyc_check_mutex(d,obj) Cyc_check_type(d,Cyc_is_mutex, mutex_tag, obj); void Cyc_invalid_type_error(void *data, int tag, object found); void Cyc_check_obj(void *data, int tag, object obj); void Cyc_check_bounds(void *data, const char *label, int len, int index); @@ -122,6 +123,9 @@ object Cyc_vector_ref(void *d, object v, object k); object Cyc_vector_set(void *d, object v, object k, object obj); object Cyc_make_vector(void *data, object cont, object len, object fill); object Cyc_list2vector(void *data, object cont, object l); +object Cyc_make_mutex(void *data); +object Cyc_lock_mutex(void *data, object obj); +object Cyc_unlock_mutex(void *data, object obj); object Cyc_number2string(void *d, object cont, object n); object Cyc_symbol2string(void *d, object cont, object sym) ; object Cyc_string2symbol(void *d, object str); @@ -162,6 +166,7 @@ object Cyc_is_real(object o); object Cyc_is_integer(object o); object Cyc_is_vector(object o); object Cyc_is_port(object o); +object Cyc_is_mutex(object o); object Cyc_is_symbol(object o); object Cyc_is_string(object o); object Cyc_is_char(object o); diff --git a/include/cyclone/types.h b/include/cyclone/types.h index 66ba61b0..40b9721c 100644 --- a/include/cyclone/types.h +++ b/include/cyclone/types.h @@ -239,10 +239,9 @@ 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.hdr.mark = gc_color_red; n.hdr.grayed = 0; n.tag = cvar_tag; n.pvar = v; -// TODO: mutex type -// thinking about maybe using cvar_type with a mutex tag -// add an alloc_mutex macro/function, because these will only go on the heap - +/* Define mutex type */ +typedef struct {gc_header_type hdr; tag_type tag; pthread_mutex_t lock;} mutex_type; +typedef mutex_type *mutex; /* Define boolean type. */ typedef struct {gc_header_type hdr; const tag_type tag; const char *pname;} boolean_type; diff --git a/runtime.c b/runtime.c index dd9c6cec..dc79c206 100644 --- a/runtime.c +++ b/runtime.c @@ -45,7 +45,7 @@ const char *tag_names[21] = { \ , "C primitive" \ , "vector" \ , "macro" \ - , "Reserved for future use" \ + , "mutex" \ , "Reserved for future use" }; void Cyc_invalid_type_error(void *data, int tag, object found) { @@ -542,6 +542,9 @@ object Cyc_display(object x, FILE *port) case cvar_tag: Cyc_display(Cyc_get_cvar(x), port); break; + case mutex_tag: + fprintf(port, "", x); + break; case boolean_tag: fprintf(port, "#%s",((boolean_type *) x)->pname); break; @@ -823,6 +826,11 @@ object Cyc_is_port(object o){ return boolean_t; return boolean_f;} +object Cyc_is_mutex(object o){ + if (!nullp(o) && !is_value_type(o) && ((list)o)->tag == mutex_tag) + return boolean_t; + return boolean_f;} + object Cyc_is_string(object o){ if (!nullp(o) && !is_value_type(o) && ((list)o)->tag == string_tag) return boolean_t; @@ -1215,6 +1223,36 @@ object Cyc_command_line_arguments(void *data, object cont) { return_closcall1(data, cont, lis); } +/** + * Create a new mutex by allocating it on the heap. This is different than + * other types of objects because by definition a mutex will be used by + * multiple threads, so no need to risk having the non-creating thread pick + * up a stack object ref by mistake. + */ +object Cyc_make_mutex(void *data) { +//typedef struct {gc_header_type hdr; tag_type tag; pthread_mutex_t lock;} mutex_type; +//typedef mutex_type *mutex; + int heap_grown; + mutex lock; + mutex_type tmp; + tmp.hdr.mark = gc_color_red; + tmp.hdr.grayed = 0; + tmp.tag = mutex_tag; + lock = gc_alloc(Cyc_heap, sizeof(mutex_type), (char *)(&tmp), (gc_thread_data *)data, &heap_grown); + if (pthread_mutex_init(&(lock->lock), NULL) != 0) { + fprintf(stderr, "Unable to make mutex\n"); + exit(1); + } +} + +object Cyc_lock_mutex(void *data, object obj) { + return boolean_t; +} + +object Cyc_unlock_mutex(void *data, object obj) { + return boolean_t; +} + object Cyc_make_vector(void *data, object cont, object len, object fill) { object v = nil; int i;