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