weak hash tables to manage live stacks

parent fa186927
#include <pthread.h> #include <pthread.h>
int gp_gc_p = 0; int gp_gc_p = 0;
// guile 2.2 internals normal API does not work in gc hooks
#define SCM_WEAK_TABLE(x) ((scm_t_weak_table *) SCM_CELL_WORD_1 (x))
typedef struct {
unsigned long hash;
scm_t_bits key;
scm_t_bits value;
} scm_t_weak_entry;
typedef struct {
scm_t_weak_entry *entries; /* the data */
scm_i_pthread_mutex_t lock; /* the lock */
scm_t_weak_table_kind kind; /* what kind of table it is */
unsigned long size; /* total number of slots. */
unsigned long n_items; /* number of items in table */
unsigned long lower; /* when to shrink */
unsigned long upper; /* when to grow */
int size_index; /* index into hashtable_size */
int min_size_index; /* minimum size_index */
} scm_t_weak_table;
static void
copy_weak_entry_gc (scm_t_weak_entry *src, scm_t_weak_entry *dst)
{
dst->key = src->key;
dst->value = src->value;
}
SCM
scm_c_weak_table_fold_in_gc (scm_t_table_fold_fn proc, void *closure,
SCM init, SCM table)
{
scm_t_weak_table *t;
scm_t_weak_entry *entries;
unsigned long k, size;
t = SCM_WEAK_TABLE (table);
size = t->size;
entries = t->entries;
for (k = 0; k < size; k++)
{
if (entries[k].hash)
{
scm_t_weak_entry copy;
copy_weak_entry_gc (&entries[k], &copy);
if (copy.key && copy.value)
{
/* Release table lock while we call the function. */
init = proc (closure,
SCM_PACK (copy.key), SCM_PACK (copy.value),
init);
}
}
}
return init;
}
inline void enlarge_stack(struct gp_stack *gp, int N, int NN) inline void enlarge_stack(struct gp_stack *gp, int N, int NN)
{ {
...@@ -198,39 +260,46 @@ int is_gc_locked() ...@@ -198,39 +260,46 @@ int is_gc_locked()
return ret; return ret;
} }
SCM sweep_folder (void* closure, SCM stack, SCM val, SCM seed)
{
gp_sweep_handle(stack);
//gp_clear_marks(stack, !isBefore);
return seed;
}
void *gp_after_mark_hook(void *hook_data, void *fn_data, void *data) void *gp_after_mark_hook(void *hook_data, void *fn_data, void *data)
{ {
#ifdef HAS_GP_GC #ifdef HAS_GP_GC
SCM pt = scm_fluid_ref(gp_stacks); if(scm_is_true(gp_stacks))
pthread_mutex_lock(&gp_gc_lock);
if(!gp_gc_p)
{ {
register_weak_keys(); pthread_mutex_lock(&gp_gc_lock);
while(SCM_CONSP(pt)) if(!gp_gc_p)
{ {
gp_sweep_handle(SCM_CAR(pt)); register_weak_keys();
//gp_clear_marks(SCM_CAR(pt), !isBefore); scm_c_weak_table_fold_in_gc
pt = SCM_CDR(pt); (sweep_folder,(void *)0, SCM_BOOL_F, gp_stacks);
} }
pthread_mutex_unlock(&gp_gc_lock);
} }
//else
//printf("locked sweep\n");
pthread_mutex_unlock(&gp_gc_lock);
#endif #endif
return (void *)0; return (void *)0;
} }
SCM before_folder (void* closure, SCM stack, SCM val, SCM seed)
{
gp_clear_marks(stack, isBefore);
return seed;
}
void *gp_before_mark_hook(void *hook_data, void *fn_data, void *data) void *gp_before_mark_hook(void *hook_data, void *fn_data, void *data)
{ {
#ifdef HAS_GP_GC #ifdef HAS_GP_GC
SCM pt = scm_fluid_ref(gp_stacks); if(scm_is_true(gp_stacks))
prepare_weak_keys();
register_weak_keys();
while(SCM_CONSP(pt))
{ {
gp_clear_marks(SCM_CAR(pt), isBefore); prepare_weak_keys();
pt = SCM_CDR(pt); register_weak_keys();
scm_c_weak_table_fold_in_gc
(before_folder,(void *)0, SCM_BOOL_F, gp_stacks);
} }
#endif #endif
return (void *)0; return (void *)0;
......
...@@ -242,6 +242,10 @@ static inline SCM *get_gp_cons_pure(struct gp_stack *gp) ...@@ -242,6 +242,10 @@ static inline SCM *get_gp_cons_pure(struct gp_stack *gp)
return GP_GETREF(cand); return GP_GETREF(cand);
} }
pthread_mutex_t gp_stacks_lock = PTHREAD_MUTEX_INITIALIZER;
#define LOCK_STACKS pthread_mutex_lock(&gp_stacks_lock)
#define UNLOCK_STACKS pthread_mutex_unlock(&gp_stacks_lock)
SCM gp_stacks = SCM_BOOL_F; SCM gp_stacks = SCM_BOOL_F;
static inline SCM *make_gp_stack(int id, int nthread, int nc, int ns, int ncs, int nfr, struct gp_stack **ggp) static inline SCM *make_gp_stack(int id, int nthread, int nc, int ns, int ncs, int nfr, struct gp_stack **ggp)
...@@ -368,9 +372,11 @@ static inline SCM *make_gp_stack(int id, int nthread, int nc, int ns, int ncs, i ...@@ -368,9 +372,11 @@ static inline SCM *make_gp_stack(int id, int nthread, int nc, int ns, int ncs, i
{ {
SCM *out = GP_GETREF(ret); SCM *out = GP_GETREF(ret);
{
SCM stacks = scm_cons(ret, scm_fluid_ref(gp_stacks)); LOCK_STACKS;
scm_fluid_set_x(gp_stacks, stacks); scm_hashq_set_x(gp_stacks, ret, SCM_BOOL_T);
UNLOCK_STACKS;
}
return out; return out;
} }
...@@ -1221,7 +1227,7 @@ static void gp_module_stack_init() ...@@ -1221,7 +1227,7 @@ static void gp_module_stack_init()
void gp_init_stacks() void gp_init_stacks()
{ {
gp_stacks = scm_make_fluid_with_default(SCM_EOL); gp_stacks = scm_make_weak_key_hash_table(scm_from_int(128));
} }
......
...@@ -4295,8 +4295,8 @@ void gp_init() ...@@ -4295,8 +4295,8 @@ void gp_init()
vlist_init(); vlist_init();
gp_init_stacks(); gp_init_stacks();
init_gpgc(); init_gpgc();
init_variables(); init_variables();
...@@ -4306,7 +4306,7 @@ void gp_init() ...@@ -4306,7 +4306,7 @@ void gp_init()
init_weak(); init_weak();
init_matching(); init_matching();
// init_prolog_vm(); // init_prolog_vm();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment