static void *_tort_object_alloc_smal(tort_mtable *mtable, size_t size) { if ( mtable ) { if ( ! mtable->gc_data ) mtable->gc_data = _type_for_size(size); if ( ++ allocs_since_gc > allocs_per_gc ) { tort_gc_collect(); allocs_since_gc = 0; } return smal_alloc(mtable->gc_data); } return smal_alloc(_type_for_size(size)); }
smal_finalizer * smal_finalizer_create(void *ptr, void (*func)(smal_finalizer *finalizer)) { smal_finalized *finalized = 0; smal_finalizer *finalizer; if ( ! ptr ) return 0; if ( smal_unlikely(! initialized) ) initialize(); smal_thread_mutex_lock(&referred_table_mutex); if ( ! (finalized = find_finalized_by_referred(ptr)) ) { if ( ! (finalized = smal_alloc(smal_finalized_type_)) ) { smal_thread_mutex_unlock(&referred_table_mutex); return 0; } finalized->referred = ptr; finalized->finalizers = 0; finalized->next = 0; smal_thread_mutex_init(&finalized->mutex); add_finalized(finalized); } smal_thread_mutex_unlock(&referred_table_mutex); smal_thread_mutex_lock(&finalized->mutex); if ( (finalizer = smal_alloc(smal_finalizer_type_)) ) { finalizer->referred = ptr; finalizer->func = func; finalizer->data = 0; finalizer->next = finalized->finalizers; finalized->finalizers = finalizer; } smal_thread_mutex_unlock(&finalized->mutex); return finalizer; }
int main(int argc, char **argv) { int alloc_id = 0; int alloc_n = 4000; my_cons *x = 0, *y = 0; smal_roots_2(x, y); my_cons_type = smal_type_for(sizeof(my_cons), my_cons_mark, 0); fprintf(stderr, "allocing for x list\n"); for ( alloc_id = 0; alloc_id < alloc_n; ++ alloc_id ) { my_cons *c = smal_alloc(my_cons_type); c->car = (void*) 1; c->cdr = x; x = c; } my_print_stats(); fprintf(stderr, "allocing for y list\n"); for ( alloc_id = 0; alloc_id < alloc_n; ++ alloc_id ) { my_cons *c = smal_alloc(my_cons_type); c->car = (void*) 2; c->cdr = y; y = c; } my_print_stats(); fprintf(stderr, "dropping some of x\n"); { my_cons *c; for ( c = x; c; c = c->cdr ) { if ( rand() % 10 > 5 ) { c->cdr = c->cdr ? ((my_cons*) c->cdr)->cdr : 0; } } } smal_collect(); my_print_stats(); fprintf(stderr, "allocing more for y list\n"); for ( alloc_id = 0; alloc_id < alloc_n; ++ alloc_id ) { my_cons *c = smal_alloc(my_cons_type); c->car = (void*) 2; c->cdr = y; y = c; } smal_collect(); my_print_stats(); x = y = 0; smal_collect(); fprintf(stderr, "dereference all\n"); my_print_stats(); { smal_stats stats = { 0 }; smal_global_stats(&stats); assert(stats.alloc_id == 12000); assert(stats.free_id == stats.alloc_id); assert(stats.capacity_n == 0); assert(stats.buffer_n == 0); } smal_roots_end(); fprintf(stdout, "\nOK\n"); fprintf(stderr, "\n%s OK\n", argv[0]); return 0; }
static void run_test() { int alloc_id; my_cons *x = 0, *y = 0; my_cons_type = smal_type_for(sizeof(my_cons), my_cons_mark, 0); for ( alloc_id = 0; alloc_id < 10000000; ++ alloc_id ) { int action = rand() % 10; x = smal_alloc(my_cons_type); ++ smal_alloc_n; x->car = x->cdr = 0; switch ( action ) { case 0: y = x; break; case 1: if ( y ) y->car = x; else y = x; break; case 2: if ( y ) y->cdr = x; else y = x; break; } #if 0 fprintf(stderr, "%d", action); fflush(stderr); #endif #if 0 if ( rand() % 100 == 0 ) { // fprintf(stderr, "\nGC\n"); smal_collect(); ++ smal_collect_n; // my_print_stats(); } if ( rand() % 100 == 0 ) { int obj_count = 0; smal_each_object(my_count_object, &obj_count); ++ smal_each_object_n; { smal_stats stats = { 0 }; smal_global_stats(&stats); assert(obj_count == stats.live_n); } // my_print_stats(); // fprintf(stderr, " object_count = %d\n", obj_count); } #endif } fprintf(stderr, "\nDONE\n"); my_print_stats(); { smal_stats stats = { 0 }; smal_global_stats(&stats); assert(stats.alloc_id == smal_alloc_n); assert(stats.free_id < stats.alloc_id); } x = y = 0; }
int main(int argc, char **argv) { int i = 0; int ncollect = 2; int alloc_id = 0; int alloc_n = 100; my_cons *x = 0, *y = 0; my_cons *xp = 0, *yp = 0; smal_type *my_cons_type_mu; /* mostly_unchanging */ smal_roots_4(x, y, xp, yp); smal_debug_set_level(smal_debug_mprotect, 9); smal_debug_set_level(smal_debug_mmap, 9); my_cons_type = smal_type_for(sizeof(my_cons), my_cons_mark, 0); { smal_type_descriptor desc; memset(&desc, 0, sizeof(desc)); desc.object_size = sizeof(my_cons); desc.mark_func = my_cons_mark; desc.mostly_unchanging = 1; my_cons_type_mu = smal_type_for_desc(&desc); } fprintf(stderr, "allocing for x list\n"); for ( alloc_id = 0; alloc_id < alloc_n; ++ alloc_id ) { my_cons *c = smal_alloc(my_cons_type); c->car = (void*) 1; c->cdr = x; x = c; } my_print_stats(); { smal_stats stats = { 0 }; smal_global_stats(&stats); assert(stats.buffer_mutations == 0); } fprintf(stderr, "collecting x after list\n"); smal_collect(); my_print_stats(); { smal_stats stats = { 0 }; smal_global_stats(&stats); assert(stats.buffer_mutations == 0); } fprintf(stderr, "allocing for y list (mostly_unchanging)\n"); for ( alloc_id = 0; alloc_id < alloc_n; ++ alloc_id ) { my_cons *c = smal_alloc(my_cons_type_mu); fprintf(stderr, " c = %p\n", c); c->car = (void*) 2; c->cdr = y; y = c; } my_print_stats(); fprintf(stderr, "collecting after x and y list\n"); smal_collect(); my_print_stats(); fprintf(stderr, "mutating y list\n"); xp = x; yp = y; while ( yp ) { yp->car = xp; yp = yp->cdr; xp = xp->cdr; } { smal_stats stats = { 0 }; smal_global_stats(&stats); assert(stats.buffer_mutations == 1); } fprintf(stderr, "collecting after mutating y list\n"); smal_collect(); my_print_stats(); { smal_stats stats = { 0 }; smal_global_stats(&stats); assert(stats.buffer_mutations == 1); } fprintf(stderr, "mutating y list, again\n"); xp = x; yp = y; while ( yp ) { yp->car = xp; yp = yp->cdr; xp = xp->cdr; } { smal_stats stats = { 0 }; smal_global_stats(&stats); assert(stats.buffer_mutations == 2); } fprintf(stderr, "collecting after mutating y list, again\n"); smal_collect(); my_print_stats(); { smal_stats stats = { 0 }; smal_global_stats(&stats); assert(stats.buffer_mutations == 2); } #if 0 fprintf(stderr, "dropping some of x\n"); { my_cons *c; for ( c = x; c; c = c->cdr ) { if ( rand() % 10 > 5 ) { c->cdr = c->cdr ? ((my_cons*) c->cdr)->cdr : 0; } } } smal_collect(); my_print_stats(); fprintf(stderr, "allocing more for y list\n"); for ( alloc_id = 0; alloc_id < alloc_n; ++ alloc_id ) { my_cons *c = smal_alloc(my_cons_type); c->car = (void*) 2; c->cdr = y; y = c; } smal_collect(); my_print_stats(); #endif x = y = 0; // smal_debug_level = 9; for ( i = 0; i < ncollect; ++ i ) { smal_collect(); fprintf(stderr, "dereference all %d\n", i); } my_print_stats(); { smal_stats stats = { 0 }; smal_global_stats(&stats); assert(stats.alloc_id == alloc_n * 2); assert(stats.free_id == stats.alloc_id); assert(stats.capacity_n == 0); assert(stats.buffer_n == 0); assert(stats.buffer_mutations == 2); } smal_roots_end(); fprintf(stderr, "\n%s OK\n", argv[0]); return 0; }