streamline GC's thread and custodian tracking
svn: r9224
This commit is contained in:
parent
eeee25d081
commit
2a17f76cec
|
@ -53,8 +53,8 @@ mistake, such as accidentally reversing the arguments to
|
||||||
@interaction[(cons (list 2 3) 1) (cons 1 (list 2 3))]
|
@interaction[(cons (list 2 3) 1) (cons 1 (list 2 3))]
|
||||||
|
|
||||||
Non-list pairs are used intentionally, sometimes. For example, the
|
Non-list pairs are used intentionally, sometimes. For example, the
|
||||||
@scheme[make-immutable-hash-table] function takes a list of pairs,
|
@scheme[make-immutable-hash] function takes a list of pairs, where the
|
||||||
where the @scheme[car] of each pair is a key and the @scheme[cdr] is an
|
@scheme[car] of each pair is a key and the @scheme[cdr] is an
|
||||||
arbitrary value.
|
arbitrary value.
|
||||||
|
|
||||||
The only thing more confusing to new Schemers than non-list pairs is
|
The only thing more confusing to new Schemers than non-list pairs is
|
||||||
|
|
|
@ -502,8 +502,8 @@ with some syntactic and name changes.
|
||||||
|
|
||||||
* Hash-table function names have changed:
|
* Hash-table function names have changed:
|
||||||
|
|
||||||
make-hash-table => make-hash make-weak-hash
|
make-hash-table => make-hasheq make-weak-hasheq
|
||||||
make-hasheq make-weak-hasheq
|
make-hash make-weak-hash
|
||||||
hash-table? => hash? hash-eq? hash-weak?
|
hash-table? => hash? hash-eq? hash-weak?
|
||||||
hash-table-get => hash-ref
|
hash-table-get => hash-ref
|
||||||
hash-table-put! => hash-set!
|
hash-table-put! => hash-set!
|
||||||
|
@ -512,6 +512,10 @@ with some syntactic and name changes.
|
||||||
hash-table-map => hash-map
|
hash-table-map => hash-map
|
||||||
.... ....
|
.... ....
|
||||||
|
|
||||||
|
IMPORTANT: The correct translation of `(make-hash-table)' is
|
||||||
|
`(make-hasheq)', not `(make-hash)'. Instead, `(make-hash)'
|
||||||
|
is equivalent to `(make-hash-table 'equal)'.
|
||||||
|
|
||||||
The new functions `hash-set' and `hash-remove' support
|
The new functions `hash-set' and `hash-remove' support
|
||||||
constant-time functional update of immutable hash tables.
|
constant-time functional update of immutable hash tables.
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,10 @@ GC2_EXTERN void GC_init_type_tags(int count, int pair, int mutable_pair, int wea
|
||||||
freedom in the layout of a weak box or ephemeron, so it performs weak
|
freedom in the layout of a weak box or ephemeron, so it performs weak
|
||||||
box traversals itself, but MzScheme gets to choose the tag.) */
|
box traversals itself, but MzScheme gets to choose the tag.) */
|
||||||
|
|
||||||
|
GC2_EXTERN void GC_register_root_custodian(void *);
|
||||||
|
/*
|
||||||
|
Registers the root custodian. */
|
||||||
|
|
||||||
GC2_EXTERN void GC_register_new_thread(void *, void *);
|
GC2_EXTERN void GC_register_new_thread(void *, void *);
|
||||||
/*
|
/*
|
||||||
Indicates that a just-allocated point is for a thread record
|
Indicates that a just-allocated point is for a thread record
|
||||||
|
|
|
@ -1290,24 +1290,24 @@ typedef short Type_Tag;
|
||||||
#ifdef NEWGC_BTC_ACCOUNT
|
#ifdef NEWGC_BTC_ACCOUNT
|
||||||
inline static int current_owner(Scheme_Custodian *c);
|
inline static int current_owner(Scheme_Custodian *c);
|
||||||
|
|
||||||
struct thread {
|
struct gc_thread_info {
|
||||||
void *thread;
|
void *thread;
|
||||||
int owner;
|
int owner;
|
||||||
struct thread *next;
|
struct gc_thread_info *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
static Mark_Proc normal_thread_mark = NULL, normal_custodian_mark = NULL, normal_cust_box_mark = NULL;
|
static Mark_Proc normal_thread_mark = NULL, normal_custodian_mark = NULL, normal_cust_box_mark = NULL;
|
||||||
static struct thread *threads = NULL;
|
static struct gc_thread_info *threads = NULL;
|
||||||
|
|
||||||
static unsigned short cust_box_tag;
|
static unsigned short cust_box_tag;
|
||||||
|
|
||||||
inline static void register_new_thread(void *t, void *c)
|
inline static void register_new_thread(void *t, void *c)
|
||||||
{
|
{
|
||||||
struct thread *work;
|
struct gc_thread_info *work;
|
||||||
|
|
||||||
work = (struct thread *)malloc(sizeof(struct thread));
|
work = (struct gc_thread_info *)malloc(sizeof(struct gc_thread_info));
|
||||||
work->owner = current_owner((Scheme_Custodian *)c);
|
work->owner = current_owner((Scheme_Custodian *)c);
|
||||||
((Scheme_Thread *)t)->gc_owner_set = work->owner;
|
((Scheme_Thread *)t)->gc_info = work;
|
||||||
work->thread = t;
|
work->thread = t;
|
||||||
work->next = threads;
|
work->next = threads;
|
||||||
threads = work;
|
threads = work;
|
||||||
|
@ -1315,20 +1315,15 @@ inline static void register_new_thread(void *t, void *c)
|
||||||
|
|
||||||
inline static void register_thread(void *t, void *c)
|
inline static void register_thread(void *t, void *c)
|
||||||
{
|
{
|
||||||
struct thread *work;
|
struct gc_thread_info *work;
|
||||||
|
|
||||||
for(work = threads; work; work = work->next)
|
work = ((Scheme_Thread *)t)->gc_info;
|
||||||
if(work->thread == t) {
|
|
||||||
work->owner = current_owner((Scheme_Custodian *)c);
|
work->owner = current_owner((Scheme_Custodian *)c);
|
||||||
((Scheme_Thread *)t)->gc_owner_set = work->owner;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
register_new_thread(t, c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static void mark_threads(int owner)
|
inline static void mark_threads(int owner)
|
||||||
{
|
{
|
||||||
struct thread *work;
|
struct gc_thread_info *work;
|
||||||
|
|
||||||
for(work = threads; work; work = work->next)
|
for(work = threads; work; work = work->next)
|
||||||
if(work->owner == owner) {
|
if(work->owner == owner) {
|
||||||
|
@ -1368,7 +1363,7 @@ inline static void mark_cust_boxes(Scheme_Custodian *cur)
|
||||||
|
|
||||||
inline static void clean_up_thread_list(void)
|
inline static void clean_up_thread_list(void)
|
||||||
{
|
{
|
||||||
struct thread *work = threads, *prev = NULL;
|
struct gc_thread_info *work = threads, *prev = NULL;
|
||||||
|
|
||||||
while(work) {
|
while(work) {
|
||||||
if(!find_page(work->thread) || marked(work->thread)) {
|
if(!find_page(work->thread) || marked(work->thread)) {
|
||||||
|
@ -1376,7 +1371,7 @@ inline static void clean_up_thread_list(void)
|
||||||
prev = work;
|
prev = work;
|
||||||
work = work->next;
|
work = work->next;
|
||||||
} else {
|
} else {
|
||||||
struct thread *next = work->next;
|
struct gc_thread_info *next = work->next;
|
||||||
|
|
||||||
if(prev) prev->next = next;
|
if(prev) prev->next = next;
|
||||||
if(!prev) threads = next;
|
if(!prev) threads = next;
|
||||||
|
@ -1388,7 +1383,7 @@ inline static void clean_up_thread_list(void)
|
||||||
|
|
||||||
inline static int thread_get_owner(void *p)
|
inline static int thread_get_owner(void *p)
|
||||||
{
|
{
|
||||||
return ((Scheme_Thread *)p)->gc_owner_set;
|
return ((Scheme_Thread *)p)->gc_info->owner;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1535,13 +1530,15 @@ inline static int create_blank_owner_set(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned int old_top;
|
unsigned int old_top;
|
||||||
|
struct ot_entry **naya;
|
||||||
|
|
||||||
for(i = 1; i < owner_table_top; i++)
|
for (i = 1; i < owner_table_top; i++) {
|
||||||
if(!owner_table[i]) {
|
if (!owner_table[i]) {
|
||||||
owner_table[i] = malloc(sizeof(struct ot_entry));
|
owner_table[i] = malloc(sizeof(struct ot_entry));
|
||||||
bzero(owner_table[i], sizeof(struct ot_entry));
|
bzero(owner_table[i], sizeof(struct ot_entry));
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
old_top = owner_table_top;
|
old_top = owner_table_top;
|
||||||
if (!owner_table_top)
|
if (!owner_table_top)
|
||||||
|
@ -1549,7 +1546,9 @@ inline static int create_blank_owner_set(void)
|
||||||
else
|
else
|
||||||
owner_table_top *= 2;
|
owner_table_top *= 2;
|
||||||
|
|
||||||
owner_table = realloc(owner_table, owner_table_top*sizeof(struct ot_entry*));
|
naya = (struct ot_entry **)malloc(owner_table_top*sizeof(struct ot_entry*));
|
||||||
|
memcpy(naya, owner_table, old_top*sizeof(struct ot_entry*));
|
||||||
|
owner_table = naya;
|
||||||
bzero((char*)owner_table + (sizeof(struct ot_entry*) * old_top),
|
bzero((char*)owner_table + (sizeof(struct ot_entry*) * old_top),
|
||||||
(owner_table_top - old_top) * sizeof(struct ot_entry*));
|
(owner_table_top - old_top) * sizeof(struct ot_entry*));
|
||||||
|
|
||||||
|
@ -1563,10 +1562,6 @@ inline static int custodian_to_owner_set(Scheme_Custodian *cust)
|
||||||
if (cust->gc_owner_set)
|
if (cust->gc_owner_set)
|
||||||
return cust->gc_owner_set;
|
return cust->gc_owner_set;
|
||||||
|
|
||||||
for(i = 1; i < owner_table_top; i++)
|
|
||||||
if(owner_table[i] && (owner_table[i]->originator == cust))
|
|
||||||
return i;
|
|
||||||
|
|
||||||
i = create_blank_owner_set();
|
i = create_blank_owner_set();
|
||||||
owner_table[i]->originator = cust;
|
owner_table[i]->originator = cust;
|
||||||
cust->gc_owner_set = i;
|
cust->gc_owner_set = i;
|
||||||
|
@ -1576,25 +1571,7 @@ inline static int custodian_to_owner_set(Scheme_Custodian *cust)
|
||||||
|
|
||||||
inline static int current_owner(Scheme_Custodian *c)
|
inline static int current_owner(Scheme_Custodian *c)
|
||||||
{
|
{
|
||||||
static int has_gotten_root_custodian = 0;
|
if (!scheme_current_thread)
|
||||||
|
|
||||||
if(!owner_table) {
|
|
||||||
owner_table = malloc(10 * sizeof(struct ot_entry*));
|
|
||||||
bzero(owner_table, 10 * sizeof(struct ot_entry*));
|
|
||||||
if(create_blank_owner_set() != 1) {
|
|
||||||
GCPRINT(GCOUTF, "Something extremely weird (and bad) has happened.\n");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!has_gotten_root_custodian && c) {
|
|
||||||
has_gotten_root_custodian = 1;
|
|
||||||
owner_table[1]->originator = c;
|
|
||||||
c->gc_owner_set = 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!scheme_current_thread)
|
|
||||||
return 1;
|
return 1;
|
||||||
else if (!c)
|
else if (!c)
|
||||||
return thread_get_owner(scheme_current_thread);
|
return thread_get_owner(scheme_current_thread);
|
||||||
|
@ -1602,6 +1579,26 @@ inline static int current_owner(Scheme_Custodian *c)
|
||||||
return custodian_to_owner_set(c);
|
return custodian_to_owner_set(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GC_register_root_custodian(void *_c)
|
||||||
|
{
|
||||||
|
Scheme_Custodian *c = (Scheme_Custodian *)_c;
|
||||||
|
|
||||||
|
if (owner_table) {
|
||||||
|
/* Reset */
|
||||||
|
free(owner_table);
|
||||||
|
owner_table = NULL;
|
||||||
|
owner_table_top = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (create_blank_owner_set() != 1) {
|
||||||
|
GCPRINT(GCOUTF, "Something extremely weird (and bad) has happened.\n");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
owner_table[1]->originator = c;
|
||||||
|
c->gc_owner_set = 1;
|
||||||
|
}
|
||||||
|
|
||||||
inline static int custodian_member_owner_set(void *cust, int set)
|
inline static int custodian_member_owner_set(void *cust, int set)
|
||||||
{
|
{
|
||||||
Scheme_Custodian_Reference *box;
|
Scheme_Custodian_Reference *box;
|
||||||
|
|
|
@ -1073,7 +1073,7 @@ typedef struct Scheme_Thread {
|
||||||
Scheme_Object *mbox_sema;
|
Scheme_Object *mbox_sema;
|
||||||
|
|
||||||
#ifdef MZ_PRECISE_GC
|
#ifdef MZ_PRECISE_GC
|
||||||
int gc_owner_set;
|
struct gc_thread_info *gc_info; /* managed by the GC */
|
||||||
#endif
|
#endif
|
||||||
} Scheme_Thread;
|
} Scheme_Thread;
|
||||||
|
|
||||||
|
|
|
@ -6332,6 +6332,9 @@ static void make_initial_config(Scheme_Thread *p)
|
||||||
REGISTER_SO(last_custodian);
|
REGISTER_SO(last_custodian);
|
||||||
REGISTER_SO(limited_custodians);
|
REGISTER_SO(limited_custodians);
|
||||||
main_custodian = scheme_make_custodian(NULL);
|
main_custodian = scheme_make_custodian(NULL);
|
||||||
|
#ifdef MZ_PRECISE_GC
|
||||||
|
GC_register_root_custodian(main_custodian);
|
||||||
|
#endif
|
||||||
last_custodian = main_custodian;
|
last_custodian = main_custodian;
|
||||||
init_param(cells, paramz, MZCONFIG_CUSTODIAN, (Scheme_Object *)main_custodian);
|
init_param(cells, paramz, MZCONFIG_CUSTODIAN, (Scheme_Object *)main_custodian);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user