inline static uintptr_t custodian_usage(NewGC*gc, void *custodian) { OTEntry **owner_table; uintptr_t retval = 0; int i; if(!gc->really_doing_accounting) { if (!gc->avoid_collection) { CHECK_PARK_UNUSED(gc); gc->park[0] = custodian; gc->really_doing_accounting = 1; garbage_collect(gc, 1, 0, 0, NULL); custodian = gc->park[0]; gc->park[0] = NULL; } } i = custodian_to_owner_set(gc, (Scheme_Custodian *)custodian); owner_table = gc->owner_table; if (owner_table[i]) retval = (owner_table[i]->memory_use + owner_table[i]->master_memory_use); else retval = 0; return gcWORDS_TO_BYTES(retval); }
inline static int current_owner(NewGC *gc, Scheme_Custodian *c) { if (!scheme_current_thread) return 1; else if (!c) return thread_get_owner(scheme_current_thread); else return custodian_to_owner_set(gc, c); }
int BTC_custodian_mark(void *p, struct NewGC *gc) { if (gc->doing_memory_accounting) { if(custodian_to_owner_set(gc, p) == gc->current_mark_owner) return gc->mark_table[btc_redirect_custodian](p, gc); else return OBJPTR_TO_OBJHEAD(p)->size; } return gc->mark_table[btc_redirect_custodian](p, gc); }
static uintptr_t BTC_get_account_hook(void *c1) { NewGC *gc = GC_get_GC(); uintptr_t mem; if (!gc->really_doing_accounting) return 0; mem = custodian_single_time_limit(gc, custodian_to_owner_set(gc, c1)); if (mem == (uintptr_t)(intptr_t)-1) return 0; return mem; }
inline static unsigned long custodian_usage(NewGC*gc, void *custodian) { OTEntry **owner_table; unsigned long retval = 0; int i; if(!gc->really_doing_accounting) { gc->park[0] = custodian; gc->really_doing_accounting = 1; garbage_collect(gc, 1, 0); custodian = gc->park[0]; gc->park[0] = NULL; } i = custodian_to_owner_set(gc, (Scheme_Custodian *)custodian); owner_table = gc->owner_table; if (owner_table[i]) retval = owner_table[i]->memory_use; else retval = 0; return gcWORDS_TO_BYTES(retval); }
static void BTC_do_accounting(NewGC *gc) { const int table_size = gc->owner_table_size; OTEntry **owner_table = gc->owner_table; if(gc->really_doing_accounting) { Scheme_Custodian *cur = owner_table[current_owner(gc, NULL)]->originator, *last, *parent; Scheme_Custodian_Reference *box = cur->global_next; int i; GCDEBUG((DEBUGOUTF, "\nBEGINNING MEMORY ACCOUNTING\n")); gc->doing_memory_accounting = 1; gc->in_unsafe_allocation_mode = 1; gc->unsafe_allocation_abort = btc_overmem_abort; gc->master_page_btc_mark_checked = 0; /* clear the memory use numbers out */ for(i = 1; i < table_size; i++) if(owner_table[i]) { owner_table[i]->memory_use = 0; #ifdef MZ_USE_PLACES if (MASTERGC && MASTERGC->major_places_gc) owner_table[i]->master_memory_use = 0; #endif } /* start with root: */ while (cur->parent && SCHEME_PTR1_VAL(cur->parent)) { cur = SCHEME_PTR1_VAL(cur->parent); } /* walk forward for the order we want (blame parents instead of children) */ last = cur; while(cur) { int owner = custodian_to_owner_set(gc, cur); uintptr_t save_count = gc->phantom_count; gc->phantom_count = 0; gc->current_mark_owner = owner; GCDEBUG((DEBUGOUTF,"MARKING THREADS OF OWNER %i (CUST %p)\n", owner, cur)); gc->kill_propagation_loop = 0; mark_threads(gc, owner); mark_cust_boxes(gc, cur); GCDEBUG((DEBUGOUTF, "Propagating accounting marks\n")); propagate_accounting_marks(gc); last = cur; box = cur->global_next; cur = box ? SCHEME_PTR1_VAL(box) : NULL; owner_table = gc->owner_table; owner_table[owner]->memory_use = add_no_overflow(owner_table[owner]->memory_use, gcBYTES_TO_WORDS(gc->phantom_count)); gc->phantom_count = save_count; } release_master_btc_mark(gc); /* walk backward folding totals int parent */ cur = last; while (cur) { int owner = custodian_to_owner_set(gc, cur); box = cur->parent; parent = box ? SCHEME_PTR1_VAL(box) : NULL; if (parent) { int powner = custodian_to_owner_set(gc, parent); owner_table = gc->owner_table; owner_table[powner]->memory_use = add_no_overflow(owner_table[powner]->memory_use, owner_table[owner]->memory_use); owner_table[powner]->master_memory_use += owner_table[owner]->master_memory_use; } box = cur->global_prev; cur = box ? SCHEME_PTR1_VAL(box) : NULL; } gc->in_unsafe_allocation_mode = 0; gc->doing_memory_accounting = 0; gc->old_btc_mark = gc->new_btc_mark; gc->new_btc_mark = !gc->new_btc_mark; } clear_stack_pages(gc); }