Skip to content

Commit

Permalink
builtin atomic_compare_exchange
Browse files Browse the repository at this point in the history
  • Loading branch information
OdnetninI committed Sep 16, 2023
1 parent f037f39 commit c67a003
Showing 1 changed file with 55 additions and 0 deletions.
55 changes: 55 additions & 0 deletions lib/std/atomic.c3
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,61 @@ macro @atomic_exec(#func, data, value, ordering) @local

module std::atomic;

macro @__atomic_compare_exchange_ordering_failure(ptr, expected, desired, $success, failure) {
switch(failure)
{
case AtomicOrdering.RELAXED.ordinal: return $$compare_exchange(ptr, expected, desired, false, false, $success, AtomicOrdering.RELAXED.ordinal, 0);
case AtomicOrdering.ACQUIRE.ordinal: return $$compare_exchange(ptr, expected, desired, false, false, $success, AtomicOrdering.ACQUIRE.ordinal, 0);
case AtomicOrdering.SEQ_CONSISTENT.ordinal: return $$compare_exchange(ptr, expected, desired, false, false, $success, AtomicOrdering.SEQ_CONSISTENT.ordinal, 0);
default: assert(false, "Unrecognized failure ordering");
}
return 0;
}

macro @__atomic_compare_exchange_ordering_success(ptr, expected, desired, success, failure)
{
switch(success)
{
case AtomicOrdering.RELAXED.ordinal: return @__atomic_compare_exchange_ordering_failure(ptr, expected, desired, AtomicOrdering.RELAXED.ordinal, failure);
case AtomicOrdering.ACQUIRE.ordinal: return @__atomic_compare_exchange_ordering_failure(ptr, expected, desired, AtomicOrdering.ACQUIRE.ordinal, failure);
case AtomicOrdering.RELEASE.ordinal: return @__atomic_compare_exchange_ordering_failure(ptr, expected, desired, AtomicOrdering.RELEASE.ordinal, failure);
case AtomicOrdering.ACQUIRE_RELEASE.ordinal: return @__atomic_compare_exchange_ordering_failure(ptr, expected, desired, AtomicOrdering.ACQUIRE_RELEASE.ordinal, failure);
case AtomicOrdering.SEQ_CONSISTENT.ordinal: return @__atomic_compare_exchange_ordering_failure(ptr, expected, desired, AtomicOrdering.SEQ_CONSISTENT.ordinal, failure);
default: assert(false, "Unrecognized success ordering");
}
return 0;
}

fn CInt __atomic_compare_exchange(CInt size, any* ptr, any* expected, any* desired, CInt success, CInt failure) @extern("__atomic_compare_exchange") @export
{
switch (size)
{
case 1:
char* pt = (char*)ptr;
char ex = *(char*)expected;
char de = *(char*)desired;
if (ex == @__atomic_compare_exchange_ordering_success(pt, ex, de, success, failure)) return 1;
case 2:
short* pt = (short*)ptr;
short ex = *(short*)expected;
short de = *(short*)desired;
if (ex == @__atomic_compare_exchange_ordering_success(pt, ex, de, success, failure)) return 1;
case 4:
int* pt = (int*)ptr;
int ex = *(int*)expected;
int de = *(int*)desired;
if (ex == @__atomic_compare_exchange_ordering_success(pt, ex, de, success, failure)) return 1;
case 8:
long* pt = (long*)ptr;
long ex = *(long*)expected;
long de = *(long*)desired;
if (ex == @__atomic_compare_exchange_ordering_success(pt, ex, de, success, failure)) return 1;
default:
assert(false, "Unsuported size (%d) for atomic_compare_exchange", size);
}
return 0;
}

/**
* @param [&in] ptr "the variable or dereferenced pointer to the data."
* @param [in] y "the value to be added to ptr."
Expand Down

0 comments on commit c67a003

Please sign in to comment.