/** * Contains a registry for GC factories. * * Copyright: Copyright Digital Mars 2016. * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). * Authors: Martin Nowak */ module core.gc.registry; import core.gc.gcinterface : GC; /*@nogc nothrow:*/ /** * A factory function that instantiates an implementation of the GC interface. * In case the instance was allocated on the C heap, it is supposed to * free itself upon calling it's destructor. * * The factory should print an error and abort the program if it * cannot successfully initialize the GC instance. */ alias GCFactory = GC function(); /** * Register a GC factory under the given `name`. This function must be called * from a C constructor before druntime is initialized. * * To use the registered GC, it's name must be specified gcopt runtime option, * e.g. by passing $(TT, --DRT-gcopt=gc:my_gc_name) as application argument. * * Params: * name = name of the GC implementation; should be unique * factory = function to instantiate the implementation * Note: The registry does not perform synchronization, as registration is * assumed to be executed serially, as is the case for C constructors. * See_Also: * $(LINK2 https://dlang.org/spec/garbage.html#gc_config, Configuring the Garbage Collector) */ void registerGCFactory(string name, GCFactory factory) nothrow @nogc { import core.stdc.stdlib : realloc; auto ptr = cast(Entry*)realloc(entries.ptr, (entries.length + 1) * Entry.sizeof); entries = ptr[0 .. entries.length + 1]; entries[$ - 1] = Entry(name, factory); } /** * Called during runtime initialization to initialize a GC instance of given `name`. * * Params: * name = name of the GC to instantiate * Returns: * The created GC instance or `null` if no factory for that name was registered */ GC createGCInstance(string name) { import core.stdc.stdlib : free; foreach (entry; entries) { if (entry.name != name) continue; auto instance = entry.factory(); // only one GC at a time for now, so free the registry to not leak free(entries.ptr); entries = null; return instance; } return null; } // list of all registerd GCs const(Entry[]) registeredGCFactories(scope int dummy=0) nothrow @nogc { return entries; } private: struct Entry { string name; GCFactory factory; } __gshared Entry[] entries;