Skip to content

Commit

Permalink
druntime: Slightly revise LDC-specifics in core.internal.atomic
Browse files Browse the repository at this point in the history
  • Loading branch information
kinke committed Feb 3, 2024
1 parent dc110f6 commit deeaced
Showing 1 changed file with 21 additions and 12 deletions.
33 changes: 21 additions & 12 deletions runtime/druntime/src/core/internal/atomic.d
Original file line number Diff line number Diff line change
Expand Up @@ -18,42 +18,56 @@ version (LDC)

pragma(inline, true):

enum IsAtomicLockFree(T) = T.sizeof <= 8 || (T.sizeof <= 16 && has128BitCAS);
enum IsAtomicLockFree(T) = is(_AtomicType!T);

inout(T) atomicLoad(MemoryOrder order = MemoryOrder.seq, T)(inout(T)* src) pure nothrow @nogc @trusted
{
static assert(order != MemoryOrder.rel && order != MemoryOrder.acq_rel,
"invalid MemoryOrder for atomicLoad()");

alias A = _AtomicType!T;
A result = llvm_atomic_load!A(cast(shared A*) src, _ordering!(order));
return *cast(inout(T)*) &result;
}

void atomicStore(MemoryOrder order = MemoryOrder.seq, T)(T* dest, T value) pure nothrow @nogc @trusted
{
static assert(order != MemoryOrder.acq && order != MemoryOrder.acq_rel,
"Invalid MemoryOrder for atomicStore()");

alias A = _AtomicType!T;
llvm_atomic_store!A(*cast(A*) &value, cast(shared A*) dest, _ordering!(order));
}

T atomicFetchAdd(MemoryOrder order = MemoryOrder.seq, T)(T* dest, T value) pure nothrow @nogc @trusted
if (is(T : ulong))
{
alias A = _AtomicType!T;
return llvm_atomic_rmw_add!A(cast(shared A*) dest, value, _ordering!(order));
}

T atomicFetchSub(MemoryOrder order = MemoryOrder.seq, T)(T* dest, T value) pure nothrow @nogc @trusted
if (is(T : ulong))
{
alias A = _AtomicType!T;
return llvm_atomic_rmw_sub!A(cast(shared A*) dest, value, _ordering!(order));
}

T atomicExchange(MemoryOrder order = MemoryOrder.seq, bool result = true, T)(T* dest, T value) pure nothrow @nogc @trusted
{
static assert(order != MemoryOrder.acq, "Invalid MemoryOrder for atomicExchange()");

alias A = _AtomicType!T;
A result = llvm_atomic_rmw_xchg!A(cast(shared A*) dest, *cast(A*) &value, _ordering!(order));
return *cast(T*) &result;
}

bool atomicCompareExchange(bool weak = false, MemoryOrder succ = MemoryOrder.seq, MemoryOrder fail = MemoryOrder.seq, T)(T* dest, T* compare, T value) pure nothrow @nogc @trusted
{
static assert(fail != MemoryOrder.rel && fail != MemoryOrder.acq_rel,
"Invalid fail MemoryOrder for atomicCompareExchange()");
static assert (succ >= fail, "The first MemoryOrder argument for atomicCompareExchange() cannot be weaker than the second argument");

alias A = _AtomicType!T;
auto result = llvm_atomic_cmp_xchg!A(cast(shared A*) dest, *cast(A*) compare, *cast(A*) &value,
_ordering!(succ), _ordering!(fail), weak);
Expand All @@ -71,6 +85,10 @@ version (LDC)

bool atomicCompareExchangeNoResult(bool weak = false, MemoryOrder succ = MemoryOrder.seq, MemoryOrder fail = MemoryOrder.seq, T)(T* dest, const T compare, T value) pure nothrow @nogc @trusted
{
static assert(fail != MemoryOrder.rel && fail != MemoryOrder.acq_rel,
"Invalid fail MemoryOrder for atomicCompareExchange()");
static assert (succ >= fail, "The first MemoryOrder argument for atomicCompareExchange() cannot be weaker than the second argument");

alias A = _AtomicType!T;
auto result = llvm_atomic_cmp_xchg!A(cast(shared A*) dest, *cast(A*) &compare, *cast(A*) &value,
_ordering!(succ), _ordering!(fail), weak);
Expand Down Expand Up @@ -165,18 +183,9 @@ version (LDC)
else static if (T.sizeof == ulong.sizeof)
alias _AtomicType = ulong;
else static if (T.sizeof == 2*ulong.sizeof && has128BitCAS)
{
struct UCent
{
ulong value1;
ulong value2;
}

alias _AtomicType = UCent;
}
alias _AtomicType = imported!"core.int128".Cent;
else
static assert(is(_AtomicType!T),
"Cannot atomically load/store type of size " ~ T.sizeof.stringof);
static assert(false, "Cannot atomically load/store type of size " ~ T.sizeof.stringof);
}
}
else: // !LDC
Expand Down

0 comments on commit deeaced

Please sign in to comment.