codepad
[
create a new paste
]
login
|
about
Language:
C
C++
D
Haskell
Lua
OCaml
PHP
Perl
Plain Text
Python
Ruby
Scheme
Tcl
module singleton; import std.concurrency; import core.atomic; import core.thread; class LockSingleton { static LockSingleton get() { __gshared LockSingleton _instance; synchronized { if (_instance is null) { _instance = new LockSingleton; } } return _instance; } private: this() { } } class SyncSingleton { static SyncSingleton get() { static bool _instantiated; // tls __gshared SyncSingleton _instance; if (!_instantiated) { synchronized { if (_instance is null) { _instance = new SyncSingleton; } _instantiated = true; } } return _instance; } private: this() { } } class AtomicSingleton { static AtomicSingleton get() { shared static bool _instantiated = false; __gshared AtomicSingleton _instance; // only enter synchronized block if not instantiated if (!atomicLoad!(MemoryOrder.acq)(_instantiated)) { synchronized { if (_instance is null) { _instance = new AtomicSingleton; } atomicStore!(MemoryOrder.rel)(_instantiated, true); } } return _instance; } } version (unittest) { ulong _thread_call_count; // TLS } unittest { import std.datetime; import std.stdio; import std.string; import std.typetuple; import std.exception; import core.atomic; foreach (TestClass; TypeTuple!(LockSingleton, SyncSingleton, AtomicSingleton)) { // mixin to avoid multiple definition errors mixin(q{ shared ulong msecs = 0; static void test_%1$s(shared ulong* counter) { auto sw = StopWatch(AutoStart.yes); foreach (i; 0 .. 1024_000) { // just trying to avoid the compiler from doing dead-code optimization _thread_call_count += enforce(TestClass.get() !is null); } sw.stop(); atomicOp!"+="(*counter, sw.peek.msecs); } enum threadCount = 4; foreach (i; 0 .. threadCount) spawn(&test_%1$s, &msecs); thread_joinAll(); }.format(TestClass.stringof)); writefln("Test time for %s: %s msecs.", TestClass.stringof, cast(double)msecs/threadCount); } } void main() { }
Private
[
?
]
Run code
Submit