atomics A.2a: CAS ops + recognizer + methods, emit bails (lock)

compare_exchange/_weak wired end-to-end except LLVM emission (bails loudly;
A.2b makes it real). New IR op atomic_cmpxchg + AtomicCmpxchg{ptr, cmp, new,
val_ty, success_ordering, failure_ordering, weak}; result type = ?T (null =
SUCCESS, failure carries the actual value for retry). print arm; emit dispatch
-> emitAtomicCmpxchg (BAILS). comptime_vm arm does real single-thread CAS (read
actual / compare / store-on-equal / build ?T: success->none, failure->some;
weak == strong at comptime). Recognizer extended (atomic_cmpxchg/_weak, 6 args)
-- CAS restricted to INTEGER T (loud reject); BOTH orderings resolved via
atomicOrderingFromNode; dual-ordering validation (failure may not be
release/acq_rel nor stronger than success, via atomicOrderingRank). Methods
compare_exchange/_weak on Atomic($T) with comptime $success/$failure: Ordering.
examples/1702 locked to the bail; examples/1186 locks a rejected ordering pair.
Suite green (718/0).
This commit is contained in:
agra
2026-06-20 10:44:31 +03:00
parent 68ed732b79
commit dca396ed1f
16 changed files with 226 additions and 12 deletions

View File

@@ -165,6 +165,7 @@ pub const Op = union(enum) {
atomic_load: AtomicLoad, // atomic load from pointer with memory ordering
atomic_store: AtomicStore, // atomic store to pointer with memory ordering
atomic_rmw: AtomicRmw, // atomic read-modify-write; result is the OLD value
atomic_cmpxchg: AtomicCmpxchg, // atomic compare-exchange; result is ?T (null = success)
// ── Struct ops ──────────────────────────────────────────────────
struct_init: Aggregate, // construct struct from field values
@@ -334,6 +335,22 @@ pub const AtomicRmw = struct {
kind: RmwKind,
};
/// Atomic compare-exchange. The result is `?T` (an Optional of `val_ty`):
/// `null` means SUCCESS (the stored value equalled `cmp`, replaced by `new`);
/// a present value is the ACTUAL current value on failure (for a retry loop).
/// `weak` permits spurious failure (LLVM `cmpxchg weak`) — at comptime it
/// behaves as a strong exchange (single-thread, no spurious failure).
pub const AtomicCmpxchg = struct {
ptr: Ref,
cmp: Ref,
new: Ref,
/// Declared element type `T` (drives byte width; the result type is `?T`).
val_ty: TypeId = .void,
success_ordering: AtomicOrdering,
failure_ordering: AtomicOrdering,
weak: bool,
};
pub const Conversion = struct {
operand: Ref,
from: TypeId,