]> git.llucax.com Git - software/dgc/cdgc.git/blob - rt/gc/cdgc/opts.d
Add eager allocation support when fork()ing
[software/dgc/cdgc.git] / rt / gc / cdgc / opts.d
1 /**
2  * This module contains the options managemente code of the garbage collector.
3  *
4  * Copyright: Copyright (C) 2010 Leandro Lucarella <http://www.llucax.com.ar/>
5  *            All rights reserved.
6  *
7  * License: Boost Software License - Version 1.0 - August 17th, 2003
8  *
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:
15  *
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.
22  *
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.
30  *
31  * Authors: Leandro Lucarella
32  */
33
34 module rt.gc.cdgc.opts;
35
36 import cstdlib = tango.stdc.stdlib;
37 import cstring = tango.stdc.string;
38
39
40 private:
41
42
43 const MAX_OPT_LEN = 256;
44
45
46 struct Options
47 {
48     uint verbose = 0;
49     char[MAX_OPT_LEN] log_file = "";
50     char[MAX_OPT_LEN] malloc_stats_file = "";
51     char[MAX_OPT_LEN] collect_stats_file = "";
52     bool sentinel = false;
53     bool mem_stomp = false;
54     bool conservative = false;
55     bool fork = true;
56     bool eager_alloc = true;
57 }
58
59 package Options options;
60
61
62 bool cstr_eq(char* s1, char* s2)
63 {
64     return cstring.strcmp(s1, s2) == 0;
65 }
66
67
68 bool parse_bool(char* value)
69 {
70     if (value[0] == '\0')
71         return true;
72     return (cstdlib.atoi(value) != 0);
73 }
74
75
76 void process_option(char* opt_name, char* opt_value)
77 {
78     if (cstr_eq(opt_name, "verbose"))
79         options.verbose = cstdlib.atoi(opt_value);
80     else if (cstr_eq(opt_name, "log_file"))
81         cstring.strcpy(options.log_file.ptr, opt_value);
82     else if (cstr_eq(opt_name, "malloc_stats_file"))
83         cstring.strcpy(options.malloc_stats_file.ptr, opt_value);
84     else if (cstr_eq(opt_name, "collect_stats_file"))
85         cstring.strcpy(options.collect_stats_file.ptr, opt_value);
86     else if (cstr_eq(opt_name, "sentinel"))
87         options.sentinel = parse_bool(opt_value);
88     else if (cstr_eq(opt_name, "mem_stomp"))
89         options.mem_stomp = parse_bool(opt_value);
90     else if (cstr_eq(opt_name, "conservative"))
91         options.conservative = parse_bool(opt_value);
92     else if (cstr_eq(opt_name, "no_fork"))
93         options.fork = !parse_bool(opt_value);
94     else if (cstr_eq(opt_name, "eager_alloc"))
95         options.eager_alloc = parse_bool(opt_value);
96 }
97
98
99 package void parse(char* opts_string)
100 {
101     char[MAX_OPT_LEN] opt_name;
102     opt_name[0] = '\0';
103     char[MAX_OPT_LEN] opt_value;
104     opt_value[0] = '\0';
105     char* curr = opt_name.ptr;
106     size_t i = 0;
107     if (opts_string is null)
108         return;
109     for (; *opts_string != '\0'; opts_string++)
110     {
111         char c = *opts_string;
112         if (i == MAX_OPT_LEN)
113         {
114             if (c != ':')
115                 continue;
116             else
117                 i--;
118         }
119         switch (*opts_string)
120         {
121         case ':':
122             curr[i] = '\0';
123             process_option(opt_name.ptr, opt_value.ptr);
124             i = 0;
125             opt_name[0] = '\0';
126             opt_value[0] = '\0';
127             curr = opt_name.ptr;
128             break;
129         case '=':
130             opt_name[i] = '\0';
131             curr = opt_value.ptr;
132             i = 0;
133             break;
134         default:
135             curr[i] = c;
136             ++i;
137         }
138     }
139     if (i == MAX_OPT_LEN)
140         i--;
141     curr[i] = '\0';
142     process_option(opt_name.ptr, opt_value.ptr);
143 }
144
145
146 unittest
147 {
148     with (options) {
149         assert (verbose == 0);
150         assert (log_file[0] == '\0');
151         assert (sentinel == false);
152         assert (mem_stomp == false);
153         assert (conservative == false);
154         assert (fork == true);
155         assert (eager_alloc == true);
156     }
157     parse("mem_stomp");
158     with (options) {
159         assert (verbose == 0);
160         assert (log_file[0] == '\0');
161         assert (sentinel == false);
162         assert (mem_stomp == true);
163         assert (conservative == false);
164         assert (fork == true);
165         assert (eager_alloc == true);
166     }
167     parse("mem_stomp=0:verbose=2:conservative:no_fork=10:eager_alloc=0");
168     with (options) {
169         assert (verbose == 2);
170         assert (log_file[0] == '\0');
171         assert (sentinel == false);
172         assert (mem_stomp == false);
173         assert (conservative == true);
174         assert (fork == false);
175         assert (eager_alloc == false);
176     }
177     parse("log_file=12345 67890:verbose=1:sentinel=4:mem_stomp=1");
178     with (options) {
179         assert (verbose == 1);
180         assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
181         assert (sentinel == true);
182         assert (mem_stomp == true);
183         assert (conservative == true);
184         assert (fork == false);
185         assert (eager_alloc == false);
186     }
187     parse(null);
188     with (options) {
189         assert (verbose == 1);
190         assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
191         assert (sentinel == true);
192         assert (mem_stomp == true);
193         assert (conservative == true);
194         assert (fork == false);
195         assert (eager_alloc == false);
196     }
197     parse("");
198     with (options) {
199         assert (verbose == 1);
200         assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
201         assert (sentinel == true);
202         assert (mem_stomp == true);
203         assert (conservative == true);
204         assert (fork == false);
205         assert (eager_alloc == false);
206     }
207     parse(":");
208     with (options) {
209         assert (verbose == 1);
210         assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
211         assert (sentinel == true);
212         assert (mem_stomp == true);
213         assert (conservative == true);
214         assert (fork == false);
215         assert (eager_alloc == false);
216     }
217     parse("::::");
218     with (options) {
219         assert (verbose == 1);
220         assert (cstring.strcmp(log_file.ptr, "12345 67890".ptr) == 0);
221         assert (sentinel == true);
222         assert (mem_stomp == true);
223         assert (conservative == true);
224         assert (fork == false);
225         assert (eager_alloc == false);
226     }
227 }
228
229
230 // vim: set et sw=4 sts=4 :