mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 20:11:17 +00:00
65 lines
3.0 KiB
Plaintext
65 lines
3.0 KiB
Plaintext
// Copyright (c) 2023 Eduardo José Gómez Hernández. All rights reserved.
|
|
// Use of this source code is governed by the MIT license
|
|
// a copy of which can be found in the LICENSE_STDLIB file.
|
|
module std::atomic;
|
|
|
|
macro @__atomic_compare_exchange_ordering_failure(ptr, expected, desired, $success, failure, $alignment)
|
|
{
|
|
switch (failure)
|
|
{
|
|
case AtomicOrdering.RELAXED.ordinal: return $$compare_exchange(ptr, expected, desired, false, false, $success, AtomicOrdering.RELAXED.ordinal, $alignment);
|
|
case AtomicOrdering.ACQUIRE.ordinal: return $$compare_exchange(ptr, expected, desired, false, false, $success, AtomicOrdering.ACQUIRE.ordinal, $alignment);
|
|
case AtomicOrdering.SEQ_CONSISTENT.ordinal: return $$compare_exchange(ptr, expected, desired, false, false, $success, AtomicOrdering.SEQ_CONSISTENT.ordinal, $alignment);
|
|
default: unreachable("Unrecognized failure ordering");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
macro @__atomic_compare_exchange_ordering_success(ptr, expected, desired, success, failure, $alignment)
|
|
{
|
|
switch (success)
|
|
{
|
|
case AtomicOrdering.RELAXED.ordinal: return @__atomic_compare_exchange_ordering_failure(ptr, expected, desired, AtomicOrdering.RELAXED.ordinal, failure, $alignment);
|
|
case AtomicOrdering.ACQUIRE.ordinal: return @__atomic_compare_exchange_ordering_failure(ptr, expected, desired, AtomicOrdering.ACQUIRE.ordinal, failure, $alignment);
|
|
case AtomicOrdering.RELEASE.ordinal: return @__atomic_compare_exchange_ordering_failure(ptr, expected, desired, AtomicOrdering.RELEASE.ordinal, failure, $alignment);
|
|
case AtomicOrdering.ACQUIRE_RELEASE.ordinal: return @__atomic_compare_exchange_ordering_failure(ptr, expected, desired, AtomicOrdering.ACQUIRE_RELEASE.ordinal, failure, $alignment);
|
|
case AtomicOrdering.SEQ_CONSISTENT.ordinal: return @__atomic_compare_exchange_ordering_failure(ptr, expected, desired, AtomicOrdering.SEQ_CONSISTENT.ordinal, failure, $alignment);
|
|
default: unreachable("Unrecognized success ordering");
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
fn CInt __atomic_compare_exchange(CInt size, any ptr, any expected, any desired, CInt success, CInt failure) @weak @export("__atomic_compare_exchange")
|
|
{
|
|
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, 1)) 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, 2)) 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, 4)) return 1;
|
|
case 8:
|
|
$if iptr.sizeof >= 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, 8)) return 1;
|
|
$else
|
|
nextcase;
|
|
$endif
|
|
default:
|
|
unreachable("Unsupported size (%d) for atomic_compare_exchange", size);
|
|
}
|
|
return 0;
|
|
}
|