1 /** 2 * Contains a registry for GC factories. 3 * 4 * Copyright: Copyright Digital Mars 2016. 5 * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 * Authors: Martin Nowak 7 */ 8 module core.gc.registry; 9 10 import core.gc.gcinterface : GC; 11 12 /*@nogc nothrow:*/ 13 14 /** 15 * A factory function that instantiates an implementation of the GC interface. 16 * In case the instance was allocated on the C heap, it is supposed to 17 * free itself upon calling it's destructor. 18 * 19 * The factory should print an error and abort the program if it 20 * cannot successfully initialize the GC instance. 21 */ 22 alias GCFactory = GC function(); 23 24 /** 25 * Register a GC factory under the given `name`. This function must be called 26 * from a C constructor before druntime is initialized. 27 * 28 * To use the registered GC, it's name must be specified gcopt runtime option, 29 * e.g. by passing $(TT, --DRT-gcopt=gc:my_gc_name) as application argument. 30 * 31 * Params: 32 * name = name of the GC implementation; should be unique 33 * factory = function to instantiate the implementation 34 * Note: The registry does not perform synchronization, as registration is 35 * assumed to be executed serially, as is the case for C constructors. 36 * See_Also: 37 * $(LINK2 https://dlang.org/spec/garbage.html#gc_config, Configuring the Garbage Collector) 38 */ 39 void registerGCFactory(string name, GCFactory factory) nothrow @nogc 40 { 41 import core.stdc.stdlib : realloc; 42 43 auto ptr = cast(Entry*)realloc(entries.ptr, (entries.length + 1) * Entry.sizeof); 44 entries = ptr[0 .. entries.length + 1]; 45 entries[$ - 1] = Entry(name, factory); 46 } 47 48 /** 49 * Called during runtime initialization to initialize a GC instance of given `name`. 50 * 51 * Params: 52 * name = name of the GC to instantiate 53 * Returns: 54 * The created GC instance or `null` if no factory for that name was registered 55 */ 56 GC createGCInstance(string name) 57 { 58 import core.stdc.stdlib : free; 59 60 foreach (entry; entries) 61 { 62 if (entry.name != name) 63 continue; 64 auto instance = entry.factory(); 65 // only one GC at a time for now, so free the registry to not leak 66 free(entries.ptr); 67 entries = null; 68 return instance; 69 } 70 return null; 71 } 72 73 // list of all registerd GCs 74 const(Entry[]) registeredGCFactories(scope int dummy=0) nothrow @nogc 75 { 76 return entries; 77 } 78 79 private: 80 81 struct Entry 82 { 83 string name; 84 GCFactory factory; 85 } 86 87 __gshared Entry[] entries;