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
8module core.gc.config;
9
10import core.stdc.stdio;
11import core.internal.parseoptions;
12
13__gshared Config config;
14
15struct 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
32    bool initialize()
33    {
34        return initConfigOptions(this, "gcopt");
35    }
36
37    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
74    string errorName() @nogc nothrow { return "GC"; }
75}
76
77private struct PrettyBytes
78{
79    long v;
80    char u; /// unit
81}
82
83pure @nogc nothrow:
84
85private PrettyBytes bytes2prettyStruct(size_t val)
86{
87    char c = prettyBytes(val);
88
89    return PrettyBytes(val, c);
90}
91
92private 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}
112unittest
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