1 /**
2 * Contains the garbage collector configuration.
3 *
4 * Copyright: Copyright Digital Mars 2016
5 * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 */
7
8 module core.gc.config;
9
10 import core.stdc.stdio;
11 import core.internal.parseoptions;
12
13 __gshared Config config;
14
15 struct Config
16 {
17 bool disable; // start disabled
18 bool fork = false; // optional concurrent behaviour
19 ubyte profile; // enable profiling with summary when terminating program
20 string gc = "conservative"; // select gc implementation conservative|precise|manual
21
22 @MemVal size_t initReserve; // initial reserve (bytes)
23 @MemVal size_t minPoolSize = 1 << 20; // initial and minimum pool size (bytes)
24 @MemVal size_t maxPoolSize = 64 << 20; // maximum pool size (bytes)
25 @MemVal size_t incPoolSize = 3 << 20; // pool size increment (bytes)
26 uint parallel = 99; // number of additional threads for marking (limited by cpuid.threadsPerCPU-1)
27 float heapSizeFactor = 2.0; // heap size to used memory ratio
28 string cleanup = "collect"; // select gc cleanup method none|collect|finalize
29
30 @nogc nothrow:
31
initializeConfig32 bool initialize()
33 {
34 return initConfigOptions(this, "gcopt");
35 }
36
helpConfig37 void help() @nogc nothrow
38 {
39 import core.gc.registry : registeredGCFactories;
40
41 printf("GC options are specified as white space separated assignments:
42 disable:0|1 - start disabled (%d)
43 fork:0|1 - set fork behaviour (%d)
44 profile:0|1|2 - enable profiling with summary when terminating program (%d)
45 gc:".ptr, disable, fork, profile);
46 foreach (i, entry; registeredGCFactories)
47 {
48 if (i) printf("|");
49 printf("%.*s", cast(int) entry.name.length, entry.name.ptr);
50 }
51 auto _initReserve = initReserve.bytes2prettyStruct;
52 auto _minPoolSize = minPoolSize.bytes2prettyStruct;
53 auto _maxPoolSize = maxPoolSize.bytes2prettyStruct;
54 auto _incPoolSize = incPoolSize.bytes2prettyStruct;
55 printf(" - select gc implementation (default = conservative)
56
57 initReserve:N - initial memory to reserve in MB (%lld%c)
58 minPoolSize:N - initial and minimum pool size in MB (%lld%c)
59 maxPoolSize:N - maximum pool size in MB (%lld%c)
60 incPoolSize:N - pool size increment MB (%lld%c)
61 parallel:N - number of additional threads for marking (%lld)
62 heapSizeFactor:N - targeted heap size to used memory ratio (%g)
63 cleanup:none|collect|finalize - how to treat live objects when terminating (collect)
64
65 Memory-related values can use B, K, M or G suffixes.
66 ".ptr,
67 _initReserve.v, _initReserve.u,
68 _minPoolSize.v, _minPoolSize.u,
69 _maxPoolSize.v, _maxPoolSize.u,
70 _incPoolSize.v, _incPoolSize.u,
71 cast(long)parallel, heapSizeFactor);
72 }
73
errorNameConfig74 string errorName() @nogc nothrow { return "GC"; }
75 }
76
77 private struct PrettyBytes
78 {
79 long v;
80 char u; /// unit
81 }
82
83 pure @nogc nothrow:
84
bytes2prettyStruct(size_t val)85 private PrettyBytes bytes2prettyStruct(size_t val)
86 {
87 char c = prettyBytes(val);
88
89 return PrettyBytes(val, c);
90 }
91
prettyBytes(ref size_t val)92 private static char prettyBytes(ref size_t val)
93 {
94 char sym = 'B';
95
96 if (val == 0)
97 return sym;
98
99 char[3] units = ['K', 'M', 'G'];
100
101 foreach (u; units)
102 if (val % (1 << 10) == 0)
103 {
104 val /= (1 << 10);
105 sym = u;
106 }
107 else if (sym != 'B')
108 break;
109
110 return sym;
111 }
112 unittest
113 {
114 size_t v = 1024;
115 assert(prettyBytes(v) == 'K');
116 assert(v == 1);
117
118 v = 1025;
119 assert(prettyBytes(v) == 'B');
120 assert(v == 1025);
121
122 v = 1024UL * 1024 * 1024 * 3;
123 assert(prettyBytes(v) == 'G');
124 assert(v == 3);
125
126 v = 1024 * 1024 + 1;
127 assert(prettyBytes(v) == 'B');
128 assert(v == 1024 * 1024 + 1);
129 }
130