2 * This module contains the options managemente code of the garbage collector.
4 * Copyright: Copyright (C) 2010 Leandro Lucarella <http://www.llucax.com.ar/>
7 * License: Boost Software License - Version 1.0 - August 17th, 2003
9 * Permission is hereby granted, free of charge, to any person or organization
10 * obtaining a copy of the software and accompanying documentation covered by
11 * this license (the "Software") to use, reproduce, display, distribute,
12 * execute, and transmit the Software, and to prepare derivative works of the
13 * Software, and to permit third-parties to whom the Software is furnished to
14 * do so, all subject to the following:
16 * The copyright notices in the Software and this entire statement, including
17 * the above license grant, this restriction and the following disclaimer,
18 * must be included in all copies of the Software, in whole or in part, and
19 * all derivative works of the Software, unless such copies or derivative
20 * works are solely in the form of machine-executable object code generated by
21 * a source language processor.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
26 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
27 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
28 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 * DEALINGS IN THE SOFTWARE.
31 * Authors: Leandro Lucarella
34 module rt.gc.cdgc.opts;
36 import cstdlib = tango.stdc.stdlib;
37 import cstring = tango.stdc.string;
38 import cerrno = tango.stdc.errno;
44 const MAX_OPT_LEN = 256;
50 char[MAX_OPT_LEN] log_file = "";
51 char[MAX_OPT_LEN] malloc_stats_file = "";
52 char[MAX_OPT_LEN] collect_stats_file = "";
53 bool sentinel = false;
54 bool mem_stomp = false;
55 bool conservative = false;
57 bool eager_alloc = true;
58 uint min_free = 15; // percent of the heap (0-100)
59 size_t prealloc_psize = 0;
60 size_t prealloc_npools = 0;
63 package Options options;
66 bool cstr_eq(char* s1, char* s2)
68 return cstring.strcmp(s1, s2) == 0;
72 bool parse_bool(char* value)
76 return (cstdlib.atoi(value) != 0);
80 void parse_prealloc(char* value)
84 long size = cstdlib.strtol(value, &end, 10);
85 if (end == value || cerrno.errno) // error parsing
87 size *= 1024 * 1024; // size is supposed to be in MiB
89 if (*end == 'x') { // number of pools specified
90 char* start = end + 1;
91 npools = cstdlib.strtol(start, &end, 10);
92 if (*end != '\0' || end == start || cerrno.errno) // error parsing
95 else if (*end != '\0') { // don't accept trailing garbage
98 if (size > 0 && npools > 0) {
99 options.prealloc_psize = size;
100 options.prealloc_npools = npools;
105 void parse_min_free(char* value)
108 long free = cstdlib.strtol(value, &end, 10);
109 if (*end != '\0' || end == value || cerrno.errno || free < 0 || free > 100)
111 options.min_free = free;
115 void process_option(char* opt_name, char* opt_value)
117 if (cstr_eq(opt_name, "verbose"))
118 options.verbose = cstdlib.atoi(opt_value);
119 else if (cstr_eq(opt_name, "log_file"))
120 cstring.strcpy(options.log_file.ptr, opt_value);
121 else if (cstr_eq(opt_name, "malloc_stats_file"))
122 cstring.strcpy(options.malloc_stats_file.ptr, opt_value);
123 else if (cstr_eq(opt_name, "collect_stats_file"))
124 cstring.strcpy(options.collect_stats_file.ptr, opt_value);
125 else if (cstr_eq(opt_name, "sentinel"))
126 options.sentinel = parse_bool(opt_value);
127 else if (cstr_eq(opt_name, "mem_stomp"))
128 options.mem_stomp = parse_bool(opt_value);
129 else if (cstr_eq(opt_name, "conservative"))
130 options.conservative = parse_bool(opt_value);
131 else if (cstr_eq(opt_name, "fork"))
132 options.fork = parse_bool(opt_value);
133 else if (cstr_eq(opt_name, "eager_alloc"))
134 options.eager_alloc = parse_bool(opt_value);
135 else if (cstr_eq(opt_name, "min_free"))
136 parse_min_free(opt_value);
137 else if (cstr_eq(opt_name, "pre_alloc"))
138 parse_prealloc(opt_value);
142 package void parse(char* opts_string)
144 char[MAX_OPT_LEN] opt_name;
146 char[MAX_OPT_LEN] opt_value;
148 char* curr = opt_name.ptr;
150 if (opts_string is null)
152 for (; *opts_string != '\0'; opts_string++)
154 char c = *opts_string;
155 if (i == MAX_OPT_LEN)
162 switch (*opts_string)
166 process_option(opt_name.ptr, opt_value.ptr);
174 curr = opt_value.ptr;
182 if (i == MAX_OPT_LEN)
185 process_option(opt_name.ptr, opt_value.ptr);
192 assert (verbose == 0);
193 assert (log_file[0] == '\0');
194 assert (sentinel == false);
195 assert (mem_stomp == false);
196 assert (conservative == false);
197 assert (fork == true);
198 assert (eager_alloc == true);
199 assert (prealloc_psize == 0);
200 assert (prealloc_npools == 0);
201 assert (min_free == 15);
205 assert (verbose == 0);
206 assert (log_file[0] == '\0');
207 assert (sentinel == false);
208 assert (mem_stomp == true);
209 assert (conservative == false);
210 assert (fork == true);
211 assert (eager_alloc == true);
212 assert (prealloc_psize == 0);
213 assert (prealloc_npools == 0);
214 assert (min_free == 15);
216 parse("mem_stomp=0:verbose=2:conservative:fork=0:eager_alloc=0");
218 assert (verbose == 2);
219 assert (log_file[0] == '\0');
220 assert (sentinel == false);
221 assert (mem_stomp == false);
222 assert (conservative == true);
223 assert (fork == false);
224 assert (eager_alloc == false);
225 assert (prealloc_psize == 0);
226 assert (prealloc_npools == 0);
227 assert (min_free == 15);
229 parse("log_file=12345 67890:verbose=1:sentinel=4:mem_stomp=1");
231 assert (verbose == 1);
232 assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
233 assert (sentinel == true);
234 assert (mem_stomp == true);
235 assert (conservative == true);
236 assert (fork == false);
237 assert (eager_alloc == false);
238 assert (prealloc_psize == 0);
239 assert (prealloc_npools == 0);
241 parse("pre_alloc:min_free=30");
243 assert (verbose == 1);
244 assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
245 assert (sentinel == true);
246 assert (mem_stomp == true);
247 assert (conservative == true);
248 assert (fork == false);
249 assert (eager_alloc == false);
250 assert (prealloc_psize == 0);
251 assert (prealloc_npools == 0);
252 assert (min_free == 30);
254 parse("pre_alloc=1");
256 assert (verbose == 1);
257 assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
258 assert (sentinel == true);
259 assert (mem_stomp == true);
260 assert (conservative == true);
261 assert (fork == false);
262 assert (eager_alloc == false);
263 assert (prealloc_psize == 1 * 1024 * 1024);
264 assert (prealloc_npools == 1);
265 assert (min_free == 30);
267 parse("pre_alloc=5a:min_free=101");
269 assert (verbose == 1);
270 assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
271 assert (sentinel == true);
272 assert (mem_stomp == true);
273 assert (conservative == true);
274 assert (fork == false);
275 assert (eager_alloc == false);
276 assert (prealloc_psize == 1 * 1024 * 1024);
277 assert (prealloc_npools == 1);
278 assert (min_free == 30);
280 parse("pre_alloc=5x:min_free=-1");
282 assert (verbose == 1);
283 assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
284 assert (sentinel == true);
285 assert (mem_stomp == true);
286 assert (conservative == true);
287 assert (fork == false);
288 assert (eager_alloc == false);
289 assert (prealloc_psize == 1 * 1024 * 1024);
290 assert (prealloc_npools == 1);
291 assert (min_free == 30);
293 parse("pre_alloc=09x010:min_free=10a");
295 assert (verbose == 1);
296 assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
297 assert (sentinel == true);
298 assert (mem_stomp == true);
299 assert (conservative == true);
300 assert (fork == false);
301 assert (eager_alloc == false);
302 assert (prealloc_psize == 9 * 1024 * 1024);
303 assert (prealloc_npools == 10);
304 assert (min_free == 30);
306 parse("pre_alloc=5x2:min_free=1.0");
308 assert (verbose == 1);
309 assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
310 assert (sentinel == true);
311 assert (mem_stomp == true);
312 assert (conservative == true);
313 assert (fork == false);
314 assert (eager_alloc == false);
315 assert (prealloc_psize == 5 * 1024 * 1024);
316 assert (prealloc_npools == 2);
317 assert (min_free == 30);
319 parse("pre_alloc=9x5x:min_free=-1");
321 assert (verbose == 1);
322 assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
323 assert (sentinel == true);
324 assert (mem_stomp == true);
325 assert (conservative == true);
326 assert (fork == false);
327 assert (eager_alloc == false);
328 assert (prealloc_psize == 5 * 1024 * 1024);
329 assert (prealloc_npools == 2);
330 assert (min_free == 30);
332 parse("pre_alloc=9x-5:min_free=0");
334 assert (verbose == 1);
335 assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
336 assert (sentinel == true);
337 assert (mem_stomp == true);
338 assert (conservative == true);
339 assert (fork == false);
340 assert (eager_alloc == false);
341 assert (prealloc_psize == 5 * 1024 * 1024);
342 assert (prealloc_npools == 2);
343 assert (min_free == 0);
345 parse("pre_alloc=0x3x0x4:min_free=100");
347 assert (verbose == 1);
348 assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
349 assert (sentinel == true);
350 assert (mem_stomp == true);
351 assert (conservative == true);
352 assert (fork == false);
353 assert (eager_alloc == false);
354 assert (prealloc_psize == 5 * 1024 * 1024);
355 assert (prealloc_npools == 2);
356 assert (min_free == 100);
360 assert (verbose == 1);
361 assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
362 assert (sentinel == true);
363 assert (mem_stomp == true);
364 assert (conservative == true);
365 assert (fork == false);
366 assert (eager_alloc == false);
367 assert (prealloc_psize == 5 * 1024 * 1024);
368 assert (prealloc_npools == 2);
369 assert (min_free == 100);
373 assert (verbose == 1);
374 assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
375 assert (sentinel == true);
376 assert (mem_stomp == true);
377 assert (conservative == true);
378 assert (fork == false);
379 assert (eager_alloc == false);
380 assert (prealloc_psize == 5 * 1024 * 1024);
381 assert (prealloc_npools == 2);
382 assert (min_free == 100);
386 assert (verbose == 1);
387 assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
388 assert (sentinel == true);
389 assert (mem_stomp == true);
390 assert (conservative == true);
391 assert (fork == false);
392 assert (eager_alloc == false);
393 assert (prealloc_psize == 5 * 1024 * 1024);
394 assert (prealloc_npools == 2);
395 assert (min_free == 100);
399 assert (verbose == 1);
400 assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
401 assert (sentinel == true);
402 assert (mem_stomp == true);
403 assert (conservative == true);
404 assert (fork == false);
405 assert (eager_alloc == false);
406 assert (prealloc_psize == 5 * 1024 * 1024);
407 assert (prealloc_npools == 2);
408 assert (min_free == 100);
413 // vim: set et sw=4 sts=4 :