diff --git a/gc.c b/gc.c index a43405e6..405f3173 100644 --- a/gc.c +++ b/gc.c @@ -341,6 +341,13 @@ char *gc_copy_obj(object dest, char *obj, gc_thread_data *thd) // NOTE: don't copy mutex itself, caller will do that (this is a special case) return (char *)hp; } + case cond_var_tag: { + cond_var_type *hp = dest; + mark(hp) = thd->gc_alloc_color; + type_of(hp) = cond_var_tag; + // NOTE: don't copy cond_var itself, caller will do that (this is a special case) + return (char *)hp; + } case forward_tag: return (char *)forward(obj); case eof_tag: @@ -469,6 +476,7 @@ size_t gc_allocated_bytes(object obj, gc_free_list *q, gc_free_list *r) if (t == port_tag) return gc_heap_align(sizeof(port_type)); if (t == cvar_tag) return gc_heap_align(sizeof(cvar_type)); if (t == mutex_tag) return gc_heap_align(sizeof(mutex_type)); + if (t == cond_var_tag) return gc_heap_align(sizeof(cond_var_type)); fprintf(stderr, "gc_allocated_bytes: unexpected object %p of type %ld\n", obj, t); exit(1); @@ -569,6 +577,14 @@ size_t gc_sweep(gc_heap *h, size_t *sum_freed_ptr) fprintf(stderr, "Error destroying mutex\n"); exit(1); } + } else if (type_of(p) == cond_var_tag) { +#if GC_DEBUG_VERBOSE + fprintf(stderr, "pthread_cond_destroy from sweep\n"); +#endif + if (pthread_cond_destroy(&(((cond_var)p)->lock)) != 0) { + fprintf(stderr, "Error destroying condition variable\n"); + exit(1); + } } // free p heap_freed += size; diff --git a/include/cyclone/runtime.h b/include/cyclone/runtime.h index 7a042b1c..446f21ef 100644 --- a/include/cyclone/runtime.h +++ b/include/cyclone/runtime.h @@ -31,6 +31,7 @@ #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); +#define Cyc_check_cond_var(d,obj) Cyc_check_type(d,Cyc_is_cond_var, cond_var_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); @@ -192,6 +193,7 @@ 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_cond_var(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 49e0cf80..a315735b 100644 --- a/include/cyclone/types.h +++ b/include/cyclone/types.h @@ -188,6 +188,7 @@ typedef long tag_type; #define vector_tag 17 #define macro_tag 18 #define mutex_tag 19 +#define cond_var_tag 20 #define nil NULL #define eq(x,y) (x == y) @@ -224,6 +225,10 @@ typedef cvar_type *cvar; typedef struct {gc_header_type hdr; tag_type tag; pthread_mutex_t lock;} mutex_type; typedef mutex_type *mutex; +/* Define condition variable type */ +typedef struct {gc_header_type hdr; tag_type tag; pthread_cond_t lock;} cond_var_type; +typedef cond_var_type *cond_var; + /* Define boolean type. */ typedef struct {gc_header_type hdr; const tag_type tag; const char *pname;} boolean_type; typedef boolean_type *boolean; diff --git a/runtime.c b/runtime.c index a91f344a..4e61a019 100644 --- a/runtime.c +++ b/runtime.c @@ -27,7 +27,7 @@ object Cyc_global_set(void *thd, object *glo, object value) /* Error checking section - type mismatch, num args, etc */ /* Type names to use for error messages */ -const char *tag_names[21] = { \ +const char *tag_names[22] = { \ "pair" \ , "symbol" \ , "" \ @@ -48,6 +48,7 @@ const char *tag_names[21] = { \ , "vector" \ , "macro" \ , "mutex" \ + , "condition variable" \ , "Reserved for future use" }; void Cyc_invalid_type_error(void *data, int tag, object found) { @@ -550,6 +551,9 @@ object Cyc_display(object x, FILE *port) case mutex_tag: fprintf(port, "", x); break; + case cond_var_tag: + fprintf(port, "", x); + break; case boolean_tag: fprintf(port, "#%s",((boolean_type *) x)->pname); break; @@ -836,6 +840,11 @@ object Cyc_is_mutex(object o){ return boolean_t; return boolean_f;} +object Cyc_is_cond_var(object o){ + if (!nullp(o) && !is_value_type(o) && ((list)o)->tag == cond_var_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;