1 /* 2 * Hunt - A refined core library for D programming language. 3 * 4 * Copyright (C) 2018-2019 HuntLabs 5 * 6 * Website: https://www.huntlabs.net/ 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.concurrency.atomic.AtomicHelper; 13 14 import core.atomic; 15 import hunt.util.Common; 16 17 class AtomicHelper { 18 static void store(T)(ref T stuff, T newVal) { 19 core.atomic.atomicStore(*(cast(shared)&stuff), cast(shared)newVal); 20 } 21 22 static T load(T)(ref T val) { 23 return core.atomic.atomicLoad(*(cast(shared)&val)); 24 } 25 26 static bool compareAndSet(T, V1, V2)(ref T stuff, V1 testVal, lazy V2 newVal) { 27 static if(is(T == interface)) { 28 import hunt.util.Common; 29 static if(CompilerHelper.isGreaterThan(2089)) { 30 return core.atomic.cas(cast(Object*)&stuff, cast(Object)testVal, cast(Object)newVal); 31 } else { 32 // FIXME: Needing refactor or cleanup -@zhangxueping at 2019-12-17T13:52:10+08:00 33 // More tests needed 34 return core.atomic.cas(cast(shared)&stuff, cast(shared)testVal, cast(shared)newVal); 35 } 36 } else { 37 return core.atomic.cas(cast(shared)&stuff, cast(shared)testVal, cast(shared)newVal); 38 } 39 // return core.atomic.cas(cast(shared)&stuff, testVal, newVal); 40 } 41 42 static T increment(T, U)(ref T stuff, U delta = 1) if (__traits(isIntegral, T)) { 43 return core.atomic.atomicOp!("+=")(stuff, delta); 44 } 45 46 static T decrement(T, U)(ref T stuff, U delta = 1) if (__traits(isIntegral, T)) { 47 return core.atomic.atomicOp!("-=")(stuff, delta); 48 } 49 50 static T getAndAdd(T, U)(ref T stuff, U delta) { 51 T v = increment(stuff, delta); 52 return v - delta; 53 } 54 55 static T getAndSet(T, U)(ref T stuff, U newValue) 56 if(__traits( compiles, { stuff = newValue; } )) { 57 static if(CompilerHelper.isGreaterThan(2088)) { 58 return cast(T)atomicExchange(cast(shared)&stuff, cast(shared)newValue); 59 } else { 60 T v = stuff; 61 store(stuff, newValue); 62 return v; 63 } 64 } 65 66 static T getAndBitwiseOr(T, U)(ref T stuff, U value) { 67 T v = stuff; 68 core.atomic.atomicOp!("|=")(stuff, value); 69 return v; 70 } 71 72 static T getAndIncrement(T)(ref T stuff) { 73 return getAndAdd(stuff, 1); 74 } 75 76 static T getAndDecrement(T)(ref T stuff) { 77 return getAndAdd(stuff, -1); 78 } 79 } 80 81 alias store = AtomicHelper.store; 82 alias load = AtomicHelper.load; 83 alias compareAndSet = AtomicHelper.compareAndSet; 84 alias increment = AtomicHelper.increment; 85 alias decrement = AtomicHelper.decrement; 86