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; } version (unittest) static void nullify() { _instance = null; } private: this() { } __gshared LockSingleton _instance; } 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; } version (unittest) static void nullify() { _instance = null; } private: this() { } __gshared SyncSingleton _instance; } 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) static void nullify() { _instance = null; _instantiated = false; } private: shared static bool _instantiated = false; __gshared AtomicSingleton _instance; } version (unittest) { ulong _thread_call_count; // TLS } unittest { import std.algorithm; import std.datetime; import std.stdio; import std.string; import std.typetuple; import std.exception; import core.atomic; enum numRuns = 10; enum threadCount = 1024; foreach(immutable _; 0 .. numRuns) { foreach (TestClass; TypeTuple!(/*LockSingleton, */SyncSingleton, AtomicSingleton)) { // mixin to avoid multiple definition errors mixin(q{ 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(); atomicStore(*counter, sw.peek.msecs); } // Not shared because dmd's Phobos won't allow to reduce() it later ulong[threadCount] timers; foreach (i; 0 .. threadCount) spawn(&test_%1$s, cast(shared(ulong*))&timers[i]); thread_joinAll(); auto grandTotal = timers.reduce!"a+b"; TestClass.nullify(); }.format(TestClass.stringof)); writefln("Test %s time for %s: %s msecs.", _, TestClass.stringof, cast(double)grandTotal/threadCount); } writeln; } } void main() { }
Private
[
?
]
Run code
Submit