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 import hunt.util.CompilerHelper; 17 18 class AtomicHelper { 19 static void store(T)(ref T stuff, T newVal) { 20 core.atomic.atomicStore(*(cast(shared)&stuff), cast(shared)newVal); 21 } 22 23 static T load(T)(ref T val) { 24 return core.atomic.atomicLoad(*(cast(shared)&val)); 25 } 26 27 static bool compareAndSet(T, V1, V2)(ref T stuff, V1 testVal, lazy V2 newVal) { 28 static if(is(T == interface)) { 29 import hunt.util.Common; 30 static if(CompilerHelper.isGreaterThan(2089)) { 31 return core.atomic.cas(cast(Object*)&stuff, cast(Object)testVal, cast(Object)newVal); 32 } else { 33 // FIXME: Needing refactor or cleanup -@zhangxueping at 2019-12-17T13:52:10+08:00 34 // More tests needed 35 return core.atomic.cas(cast(shared)&stuff, cast(shared)testVal, cast(shared)newVal); 36 } 37 } else { 38 return core.atomic.cas(cast(shared)&stuff, cast(shared)testVal, cast(shared)newVal); 39 } 40 // return core.atomic.cas(cast(shared)&stuff, testVal, newVal); 41 } 42 43 static T increment(T, U)(ref T stuff, U delta = 1) if (__traits(isIntegral, T)) { 44 return core.atomic.atomicOp!("+=")(stuff, delta); 45 } 46 47 static T decrement(T, U)(ref T stuff, U delta = 1) if (__traits(isIntegral, T)) { 48 return core.atomic.atomicOp!("-=")(stuff, delta); 49 } 50 51 static T getAndAdd(T, U)(ref T stuff, U delta) { 52 T v = increment(stuff, delta); 53 return v - delta; 54 } 55 56 static T getAndSet(T, U)(ref T stuff, U newValue) 57 if(__traits( compiles, { stuff = newValue; } )) { 58 static if(CompilerHelper.isGreaterThan(2088)) { 59 return cast(T)atomicExchange(cast(shared)&stuff, cast(shared)newValue); 60 } else { 61 T v = stuff; 62 store(stuff, newValue); 63 return v; 64 } 65 } 66 67 static T getAndBitwiseOr(T, U)(ref T stuff, U value) { 68 T v = stuff; 69 core.atomic.atomicOp!("|=")(stuff, value); 70 return v; 71 } 72 73 static T getAndIncrement(T)(ref T stuff) { 74 return getAndAdd(stuff, 1); 75 } 76 77 static T getAndDecrement(T)(ref T stuff) { 78 return getAndAdd(stuff, -1); 79 } 80 } 81 82 alias store = AtomicHelper.store; 83 alias load = AtomicHelper.load; 84 alias compareAndSet = AtomicHelper.compareAndSet; 85 alias increment = AtomicHelper.increment; 86 alias decrement = AtomicHelper.decrement; 87