int main(int argc, char **argv) { int i; int model, model_min, model_max; testobj_t *keep_arr; GC_INIT(); GC_init_finalized_malloc(); keep_arr = GC_MALLOC(sizeof(void *)*KEEP_CNT); if (argc == 2 && strcmp(argv[1], "--help") == 0) { fprintf(stderr, "Usage: %s [FINALIZATION_MODEL]\n" "\t0 -- original finalization\n" "\t1 -- finalization on reclaim\n" "\t2 -- no finalization\n", argv[0]); return 1; } if (argc == 2) { model_min = model_max = atoi(argv[1]); if (model_min < 0 || model_max > 2) exit(2); } else { model_min = 0; model_max = 2; } printf("\t\t\tfin. ratio time/s time/fin.\n"); for (model = model_min; model <= model_max; ++model) { double t = 0.0; free_count = 0; # ifdef CLOCK_TYPE CLOCK_TYPE tI, tF; GET_TIME(tI); # endif for (i = 0; i < ALLOC_CNT; ++i) { int k = rand() % KEEP_CNT; keep_arr[k] = testobj_new(model); } GC_gcollect(); # ifdef CLOCK_TYPE GET_TIME(tF); t = MS_TIME_DIFF(tF, tI)*1e-3; # endif if (model < 2) printf("%20s: %12.4lf %12lg %12lg\n", model_str[model], free_count/(double)ALLOC_CNT, t, t/free_count); else printf("%20s: %12.4lf %12lg %12s\n", model_str[model], 0.0, t, "N/A"); } return 0; }
/* * Reclaim all small blocks waiting to be reclaimed. * Abort and return FALSE when/if (*stop_func)() returns TRUE. * If this returns TRUE, then it's safe to restart the world * with incorrectly cleared mark bits. * If ignore_old is TRUE, then reclaim only blocks that have been * recently reclaimed, and discard the rest. * Stop_func may be 0. */ GC_INNER GC_bool GC_reclaim_all(GC_stop_func stop_func, GC_bool ignore_old) { word sz; unsigned kind; hdr * hhdr; struct hblk * hbp; struct obj_kind * ok; struct hblk ** rlp; struct hblk ** rlh; # ifndef SMALL_CONFIG CLOCK_TYPE start_time = 0; /* initialized to prevent warning. */ CLOCK_TYPE done_time; if (GC_print_stats == VERBOSE) GET_TIME(start_time); # endif for (kind = 0; kind < GC_n_kinds; kind++) { ok = &(GC_obj_kinds[kind]); rlp = ok -> ok_reclaim_list; if (rlp == 0) continue; for (sz = 1; sz <= MAXOBJGRANULES; sz++) { rlh = rlp + sz; while ((hbp = *rlh) != 0) { if (stop_func != (GC_stop_func)0 && (*stop_func)()) { return(FALSE); } hhdr = HDR(hbp); *rlh = hhdr -> hb_next; if (!ignore_old || hhdr -> hb_last_reclaimed == GC_gc_no - 1) { /* It's likely we'll need it this time, too */ /* It's been touched recently, so this */ /* shouldn't trigger paging. */ GC_reclaim_small_nonempty_block(hbp, FALSE); } } } } # ifndef SMALL_CONFIG if (GC_print_stats == VERBOSE) { GET_TIME(done_time); GC_log_printf("Disposing of reclaim lists took %lu msecs\n", MS_TIME_DIFF(done_time,start_time)); } # endif return(TRUE); }
STATIC int GC_CALLBACK GC_timeout_stop_func (void) { CLOCK_TYPE current_time; static unsigned count = 0; unsigned long time_diff; if ((*GC_default_stop_func)()) return(1); if ((count++ & 3) != 0) return(0); GET_TIME(current_time); time_diff = MS_TIME_DIFF(current_time,GC_start_time); if (time_diff >= GC_time_limit) { GC_COND_LOG_PRINTF( "Abandoning stopped marking after %lu msecs (attempt %d)\n", time_diff, GC_n_attempts); return(1); } return(0); }