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 */
registerGCFactory(string name,GCFactory factory)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 */
createGCInstance(string name)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;
88