weak hash tables to manage live stacks

parent fa186927
#include <pthread.h>
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)
{
......@@ -198,39 +260,46 @@ int is_gc_locked()
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)
{
#ifdef HAS_GP_GC
SCM pt = scm_fluid_ref(gp_stacks);
pthread_mutex_lock(&gp_gc_lock);
if(!gp_gc_p)
if(scm_is_true(gp_stacks))
{
register_weak_keys();
while(SCM_CONSP(pt))
{
gp_sweep_handle(SCM_CAR(pt));
//gp_clear_marks(SCM_CAR(pt), !isBefore);
pt = SCM_CDR(pt);
}
pthread_mutex_lock(&gp_gc_lock);
if(!gp_gc_p)
{
register_weak_keys();
scm_c_weak_table_fold_in_gc
(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
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)
{
#ifdef HAS_GP_GC
SCM pt = scm_fluid_ref(gp_stacks);
prepare_weak_keys();
register_weak_keys();
while(SCM_CONSP(pt))
if(scm_is_true(gp_stacks))
{
gp_clear_marks(SCM_CAR(pt), isBefore);
pt = SCM_CDR(pt);
prepare_weak_keys();
register_weak_keys();
scm_c_weak_table_fold_in_gc
(before_folder,(void *)0, SCM_BOOL_F, gp_stacks);
}
#endif
return (void *)0;
......
......@@ -242,6 +242,10 @@ static inline SCM *get_gp_cons_pure(struct gp_stack *gp)
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;
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
{
SCM *out = GP_GETREF(ret);
SCM stacks = scm_cons(ret, scm_fluid_ref(gp_stacks));
scm_fluid_set_x(gp_stacks, stacks);
{
LOCK_STACKS;
scm_hashq_set_x(gp_stacks, ret, SCM_BOOL_T);
UNLOCK_STACKS;
}
return out;
}
......@@ -1221,7 +1227,7 @@ static void gp_module_stack_init()
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()
vlist_init();
gp_init_stacks();
init_gpgc();
init_variables();
......@@ -4306,7 +4306,7 @@ void gp_init()
init_weak();
init_matching();
// 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