disclaim_bench.c raw

   1  /*
   2   * Copyright (c) 2011 by Hewlett-Packard Company.  All rights reserved.
   3   *
   4   * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
   5   * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
   6   *
   7   * Permission is hereby granted to use or copy this program
   8   * for any purpose, provided the above notices are retained on all copies.
   9   * Permission to modify the code and to distribute modified code is granted,
  10   * provided the above notices are retained, and a notice that the code was
  11   * modified is included with the above copyright notice.
  12   */
  13  
  14  #ifdef HAVE_CONFIG_H
  15  #  include "config.h"
  16  #endif
  17  
  18  #include "gc/gc_disclaim.h"
  19  
  20  #define NOT_GCBUILD
  21  #include "private/gc_priv.h"
  22  
  23  #include <string.h>
  24  
  25  #undef rand
  26  static GC_RAND_STATE_T seed;
  27  #define rand() GC_RAND_NEXT(&seed)
  28  
  29  #define my_assert(e)                                                   \
  30    if (!(e)) {                                                          \
  31      fprintf(stderr, "Assertion failure, line %d: " #e "\n", __LINE__); \
  32      exit(-1);                                                          \
  33    }
  34  
  35  #define CHECK_OUT_OF_MEMORY(p)            \
  36    do {                                    \
  37      if (NULL == (p)) {                    \
  38        fprintf(stderr, "Out of memory\n"); \
  39        exit(69);                           \
  40      }                                     \
  41    } while (0)
  42  
  43  static int free_count = 0;
  44  
  45  struct testobj_s {
  46    struct testobj_s *keep_link;
  47    int i;
  48  };
  49  
  50  typedef struct testobj_s *testobj_t;
  51  
  52  static void GC_CALLBACK
  53  testobj_finalize(void *obj, void *carg)
  54  {
  55    ++*(int *)carg;
  56    my_assert(((testobj_t)obj)->i == 109);
  57    ((testobj_t)obj)->i = 110;
  58  }
  59  
  60  static const struct GC_finalizer_closure fclos
  61      = { testobj_finalize, &free_count };
  62  
  63  static testobj_t
  64  testobj_new(int model)
  65  {
  66    testobj_t obj;
  67    switch (model) {
  68  #ifndef GC_NO_FINALIZATION
  69    case 0:
  70      obj = (struct testobj_s *)GC_malloc(sizeof(struct testobj_s));
  71      if (obj != NULL)
  72        GC_register_finalizer_no_order(obj, testobj_finalize, &free_count, NULL,
  73                                       NULL);
  74      break;
  75  #endif
  76    case 1:
  77      obj = (testobj_t)GC_finalized_malloc(sizeof(struct testobj_s), &fclos);
  78      break;
  79    case 2:
  80      obj = (struct testobj_s *)GC_malloc(sizeof(struct testobj_s));
  81      break;
  82    default:
  83      exit(-1);
  84    }
  85    CHECK_OUT_OF_MEMORY(obj);
  86    my_assert(obj->i == 0 && obj->keep_link == NULL);
  87    obj->i = 109;
  88    return obj;
  89  }
  90  
  91  #define ALLOC_CNT (2 * 1024 * 1024)
  92  #define KEEP_CNT (32 * 1024)
  93  
  94  static char const *model_str[3]
  95      = { "regular finalization", "finalize on reclaim", "no finalization" };
  96  
  97  int
  98  main(int argc, const char *argv[])
  99  {
 100    int i;
 101    int model, model_min, model_max;
 102    testobj_t *keep_arr;
 103  
 104    GC_INIT();
 105    GC_init_finalized_malloc();
 106    if (argc == 2 && strcmp(argv[1], "--help") == 0) {
 107      fprintf(stderr,
 108              "Usage: %s [FINALIZATION_MODEL]\n"
 109              "\t0 -- original finalization\n"
 110              "\t1 -- finalization on reclaim\n"
 111              "\t2 -- no finalization\n",
 112              argv[0]);
 113      return 1;
 114    }
 115    if (argc == 2) {
 116      model_min = model_max = (int)COVERT_DATAFLOW(atoi(argv[1]));
 117      if (model_min < 0 || model_max > 2)
 118        exit(2);
 119    } else {
 120  #ifndef GC_NO_FINALIZATION
 121      model_min = 0;
 122  #else
 123      model_min = 1;
 124  #endif
 125      model_max = 2;
 126    }
 127    if (GC_get_find_leak())
 128      printf("This test program is not designed for leak detection mode\n");
 129  
 130    keep_arr = (testobj_t *)GC_malloc(sizeof(void *) * KEEP_CNT);
 131    CHECK_OUT_OF_MEMORY(keep_arr);
 132    printf("\t\t\tfin. ratio       time/s    time/fin.\n");
 133    for (model = model_min; model <= model_max; ++model) {
 134      double t = 0.0;
 135  #ifndef NO_CLOCK
 136      CLOCK_TYPE tI, tF;
 137  
 138      GET_TIME(tI);
 139  #endif
 140      free_count = 0;
 141      for (i = 0; i < ALLOC_CNT; ++i) {
 142        int k = rand() % KEEP_CNT;
 143        keep_arr[k] = testobj_new(model);
 144      }
 145      GC_gcollect();
 146  #ifndef NO_CLOCK
 147      GET_TIME(tF);
 148      t = (double)MS_TIME_DIFF(tF, tI) * 1e-3;
 149  #endif
 150  
 151  #ifdef EMBOX
 152      /* Workaround some issue with "%g" processing in Embox `libc`. */
 153  #  define PRINTF_SPEC_12g "%12f"
 154  #else
 155  #  define PRINTF_SPEC_12g "%12g"
 156  #endif
 157      if (model < 2 && free_count > 0) {
 158        printf("%20s: %12.4f " PRINTF_SPEC_12g " " PRINTF_SPEC_12g "\n",
 159               model_str[model], free_count / (double)ALLOC_CNT, t,
 160               t / free_count);
 161      } else {
 162        printf("%20s: %12.4f " PRINTF_SPEC_12g " %12s\n", model_str[model], 0.0,
 163               t, "N/A");
 164      }
 165    }
 166    return 0;
 167  }
 168