Reduce macro inlining size. Remove non-const atomic ordering.

This commit is contained in:
Christoffer Lerno
2026-02-15 00:43:29 +01:00
parent a78a169a17
commit d7cf8fa9ab
2 changed files with 49 additions and 103 deletions

View File

@@ -1,9 +1,9 @@
// Copyright (c) 2023-2025 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::types <Type>;
module std::atomic::types;
struct Atomic
struct Atomic <Type>
{
Type data;
}
@@ -11,147 +11,87 @@ struct Atomic
<*
Loads data atomically, by default this uses SEQ_CONSISTENT ordering.
@param ordering : "The ordering, cannot be release or acquire-release."
@require ordering != RELEASE && ordering != ACQUIRE_RELEASE : "Release and acquire-release are not valid for load"
@param $ordering : "The ordering, cannot be release or acquire-release."
@require $ordering != RELEASE && $ordering != ACQUIRE_RELEASE : "Release and acquire-release are not valid for load"
*>
macro Type Atomic.load(&self, AtomicOrdering ordering = SEQ_CONSISTENT)
macro Type Atomic.load(&self, AtomicOrdering $ordering = SEQ_CONSISTENT)
{
Type* data = &self.data;
switch(ordering)
{
case NOT_ATOMIC: return $$atomic_load(data, false, AtomicOrdering.NOT_ATOMIC.ordinal);
case UNORDERED: return $$atomic_load(data, false, AtomicOrdering.UNORDERED.ordinal);
case RELAXED: return $$atomic_load(data, false, AtomicOrdering.RELAXED.ordinal);
case ACQUIRE: return $$atomic_load(data, false, AtomicOrdering.ACQUIRE.ordinal);
case SEQ_CONSISTENT: return $$atomic_load(data, false, AtomicOrdering.SEQ_CONSISTENT.ordinal);
case ACQUIRE_RELEASE:
case RELEASE: unreachable("Invalid ordering.");
}
return $$atomic_load(&self.data, false, $ordering.ordinal);
}
<*
Stores data atomically, by default this uses SEQ_CONSISTENT ordering.
@param ordering : "The ordering, cannot be acquire or acquire-release."
@require ordering != ACQUIRE && ordering != ACQUIRE_RELEASE : "Acquire and acquire-release are not valid for store"
@param $ordering : "The ordering, cannot be acquire or acquire-release."
@require $ordering != ACQUIRE && $ordering != ACQUIRE_RELEASE : "Acquire and acquire-release are not valid for store"
*>
macro void Atomic.store(&self, Type value, AtomicOrdering ordering = SEQ_CONSISTENT)
macro void Atomic.store(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT)
{
Type* data = &self.data;
switch(ordering)
{
case NOT_ATOMIC: $$atomic_store(data, value, false, AtomicOrdering.NOT_ATOMIC.ordinal);
case UNORDERED: $$atomic_store(data, value, false, AtomicOrdering.UNORDERED.ordinal);
case RELAXED: $$atomic_store(data, value, false, AtomicOrdering.RELAXED.ordinal);
case RELEASE: $$atomic_store(data, value, false, AtomicOrdering.RELEASE.ordinal);
case SEQ_CONSISTENT: $$atomic_store(data, value, false, AtomicOrdering.SEQ_CONSISTENT.ordinal);
case ACQUIRE_RELEASE:
case ACQUIRE: unreachable("Invalid ordering.");
}
$$atomic_store(&self.data, value, false, $ordering.ordinal);
}
macro Type Atomic.add(&self, Type value, AtomicOrdering ordering = SEQ_CONSISTENT)
macro Type Atomic.add(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT)
{
Type* data = &self.data;
return @atomic_exec(atomic::fetch_add, data, value, ordering);
return atomic::fetch_add(&self.data, value, $ordering);
}
macro Type Atomic.sub(&self, Type value, AtomicOrdering ordering = SEQ_CONSISTENT)
macro Type Atomic.sub(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT)
{
Type* data = &self.data;
return @atomic_exec(atomic::fetch_sub, data, value, ordering);
return atomic::fetch_sub(&self.data, value, $ordering);
}
macro Type Atomic.mul(&self, Type value, AtomicOrdering ordering = SEQ_CONSISTENT)
macro Type Atomic.mul(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT)
{
Type* data = &self.data;
return @atomic_exec(atomic::fetch_mul, data, value, ordering);
return atomic::fetch_mul(&self.data, value, $ordering);
}
macro Type Atomic.div(&self, Type value, AtomicOrdering ordering = SEQ_CONSISTENT)
macro Type Atomic.div(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT)
{
Type* data = &self.data;
return @atomic_exec(atomic::fetch_div, data, value, ordering);
return atomic::fetch_div(&self.data, value, $ordering);
}
macro Type Atomic.max(&self, Type value, AtomicOrdering ordering = SEQ_CONSISTENT)
macro Type Atomic.max(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT)
{
Type* data = &self.data;
return @atomic_exec(atomic::fetch_max, data, value, ordering);
return atomic::fetch_max(&self.data, value, $ordering);
}
macro Type Atomic.min(&self, Type value, AtomicOrdering ordering = SEQ_CONSISTENT)
macro Type Atomic.min(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT)
{
Type* data = &self.data;
return @atomic_exec(atomic::fetch_min, data, value, ordering);
return atomic::fetch_min(&self.data, value, $ordering);
}
macro Type Atomic.or(&self, Type value, AtomicOrdering ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT)
macro Type Atomic.or(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT)
{
Type* data = &self.data;
return @atomic_exec(atomic::fetch_or, data, value, ordering);
return atomic::fetch_or(&self.data, value, $ordering);
}
macro Type Atomic.xor(&self, Type value, AtomicOrdering ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT)
macro Type Atomic.xor(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT)
{
Type* data = &self.data;
return @atomic_exec(atomic::fetch_xor, data, value, ordering);
return atomic::fetch_xor(&self.data, value, $ordering);
}
macro Type Atomic.and(&self, Type value, AtomicOrdering ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT)
macro Type Atomic.and(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT)
{
Type* data = &self.data;
return @atomic_exec(atomic::fetch_and, data, value, ordering);
return atomic::fetch_and(&self.data, value, $ordering);
}
macro Type Atomic.shr(&self, Type amount, AtomicOrdering ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT)
macro Type Atomic.shr(&self, Type amount, AtomicOrdering $ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT)
{
Type* data = &self.data;
return @atomic_exec(atomic::fetch_shift_right, data, amount, ordering);
return atomic::fetch_shift_right(&self.data, amount, $ordering);
}
macro Type Atomic.shl(&self, Type amount, AtomicOrdering ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT)
macro Type Atomic.shl(&self, Type amount, AtomicOrdering $ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT)
{
Type* data = &self.data;
return @atomic_exec(atomic::fetch_shift_left, data, amount, ordering);
return atomic::fetch_shift_left(&self.data, amount, $ordering);
}
macro Type Atomic.set(&self, AtomicOrdering ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) == BOOL)
macro Type Atomic.set(&self, AtomicOrdering $ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) == BOOL)
{
Type* data = &self.data;
return @atomic_exec_no_arg(atomic::flag_set, data, ordering);
return atomic::flag_set(&self.data, $ordering);
}
macro Type Atomic.clear(&self, AtomicOrdering ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) == BOOL)
macro Type Atomic.clear(&self, AtomicOrdering $ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) == BOOL)
{
Type* data = &self.data;
return @atomic_exec_no_arg(atomic::flag_clear, data, ordering);
}
macro @atomic_exec(#func, data, value, ordering) @local
{
switch(ordering)
{
case RELAXED: return #func(data, value, RELAXED);
case ACQUIRE: return #func(data, value, ACQUIRE);
case RELEASE: return #func(data, value, RELEASE);
case ACQUIRE_RELEASE: return #func(data, value, ACQUIRE_RELEASE);
case SEQ_CONSISTENT: return #func(data, value, SEQ_CONSISTENT);
default: unreachable("Ordering may not be non-atomic or unordered.");
}
}
macro @atomic_exec_no_arg(#func, data, ordering) @local
{
switch(ordering)
{
case RELAXED: return #func(data, RELAXED);
case ACQUIRE: return #func(data, ACQUIRE);
case RELEASE: return #func(data, RELEASE);
case ACQUIRE_RELEASE: return #func(data, ACQUIRE_RELEASE);
case SEQ_CONSISTENT: return #func(data, SEQ_CONSISTENT);
default: unreachable("Ordering may not be non-atomic or unordered.");
}
return atomic::flag_clear(&self.data, $ordering);
}
module std::atomic;

View File

@@ -89,9 +89,12 @@ macro abs(x) => $$abs(x);
*>
macro bool is_approx(x, y, eps)
{
if (x == y) return true;
if (is_nan(x) || is_nan(y)) return false;
return abs(x - y) <= eps;
return fn bool($typeof(x) a, $typeof(y) b, $typeof(eps) eps)
{
if (a == b) return true;
if (is_nan(a) || is_nan(b)) return false;
return abs(a - b) <= eps;
}(x, y, eps);
}
<*
@@ -100,9 +103,12 @@ macro bool is_approx(x, y, eps)
*>
macro bool is_approx_rel(x, y, eps)
{
if (x == y) return true;
if (is_nan(x) || is_nan(y)) return false;
return abs(x - y) <= eps * max(abs(x), abs(y));
return fn bool($typeof(x) a, $typeof(y) b, $typeof(eps) eps)
{
if (a == b) return true;
if (is_nan(a) || is_nan(b)) return false;
return abs(a - b) <= eps * max(abs(a), abs(b));
}(x, y, eps);
}
<*
@@ -474,7 +480,7 @@ macro round(x) => $$round(x);
macro round_to_decimals(x, int decimal_places)
{
var div = $$pow_int(($typeof(x))10, decimal_places);
return round(div * x) / div;
return $$round(div * x) / div;
}
<*