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 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 77 private struct PrettyBytes 78 { 79 long v; 80 char u; /// unit 81 } 82 83 pure @nogc nothrow: 84 85 private PrettyBytes bytes2prettyStruct(size_t val) 86 { 87 char c = prettyBytes(val); 88 89 return PrettyBytes(val, c); 90 } 91 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 }