/* * Copyright (c) 2011 by Hewlett-Packard Company. All rights reserved. * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. * * Permission is hereby granted to use or copy this program * for any purpose, provided the above notices are retained on all copies. * Permission to modify the code and to distribute modified code is granted, * provided the above notices are retained, and a notice that the code was * modified is included with the above copyright notice. * */ #include #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "gc/gc_disclaim.h" #define NOT_GCBUILD #include "private/gc_priv.h" #ifdef LINT2 # undef rand static GC_RAND_STATE_T seed; # define rand() GC_RAND_NEXT(&seed) #endif #define my_assert(e) \ if (!(e)) { \ fprintf(stderr, "Assertion failure, line %d: " #e "\n", __LINE__); \ exit(-1); \ } static int free_count = 0; struct testobj_s { struct testobj_s *keep_link; int i; }; typedef struct testobj_s *testobj_t; void GC_CALLBACK testobj_finalize(void *obj, void *carg) { ++*(int *)carg; my_assert(((testobj_t)obj)->i == 109); ((testobj_t)obj)->i = 110; } static const struct GC_finalizer_closure fclos = { testobj_finalize, &free_count }; testobj_t testobj_new(int model) { testobj_t obj; switch (model) { # ifndef GC_NO_FINALIZATION case 0: obj = (struct testobj_s *)GC_malloc(sizeof(struct testobj_s)); if (obj != NULL) GC_register_finalizer_no_order(obj, testobj_finalize, &free_count, NULL, NULL); break; # endif case 1: obj = (testobj_t)GC_finalized_malloc(sizeof(struct testobj_s), &fclos); break; case 2: obj = (struct testobj_s *)GC_malloc(sizeof(struct testobj_s)); break; default: exit(-1); } if (obj == NULL) { fprintf(stderr, "Out of memory!\n"); exit(3); } my_assert(obj->i == 0 && obj->keep_link == NULL); obj->i = 109; return obj; } #define ALLOC_CNT (2*1024*1024) #define KEEP_CNT (32*1024) static char const *model_str[3] = { "regular finalization", "finalize on reclaim", "no finalization" }; int main(int argc, char **argv) { int i; int model, model_min, model_max; testobj_t *keep_arr; GC_INIT(); GC_init_finalized_malloc(); 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 = (int)COVERT_DATAFLOW(atoi(argv[1])); if (model_min < 0 || model_max > 2) exit(2); } else { # ifndef GC_NO_FINALIZATION model_min = 0; # else model_min = 1; # endif model_max = 2; } if (GC_get_find_leak()) printf("This test program is not designed for leak detection mode\n"); keep_arr = (testobj_t *)GC_malloc(sizeof(void *) * KEEP_CNT); if (NULL == keep_arr) { fprintf(stderr, "Out of memory!\n"); exit(3); } printf("\t\t\tfin. ratio time/s time/fin.\n"); for (model = model_min; model <= model_max; ++model) { double t = 0.0; # ifndef NO_CLOCK CLOCK_TYPE tI, tF; GET_TIME(tI); # endif free_count = 0; for (i = 0; i < ALLOC_CNT; ++i) { int k = rand() % KEEP_CNT; keep_arr[k] = testobj_new(model); } GC_gcollect(); # ifndef NO_CLOCK GET_TIME(tF); t = MS_TIME_DIFF(tF, tI)*1e-3; # endif if (model < 2 && free_count > 0) printf("%20s: %12.4f %12g %12g\n", model_str[model], free_count/(double)ALLOC_CNT, t, t/free_count); else printf("%20s: %12.4f %12g %12s\n", model_str[model], 0.0, t, "N/A"); } return 0; }