vyre_reference/
atomics.rs1use vyre::ir::AtomicOp;
8
9use vyre::Error;
10
11pub fn apply(
18 op: AtomicOp,
19 old: u32,
20 expected: Option<u32>,
21 value: u32,
22) -> Result<(u32, u32), vyre::Error> {
23 match op {
24 AtomicOp::Add => Ok(atomic_add(old, value)),
25 AtomicOp::Or => Ok(atomic_or(old, value)),
26 AtomicOp::And => Ok(atomic_and(old, value)),
27 AtomicOp::Xor => Ok(atomic_xor(old, value)),
28 AtomicOp::Min => Ok(atomic_min(old, value)),
29 AtomicOp::Max => Ok(atomic_max(old, value)),
30 AtomicOp::Exchange => Ok(atomic_exchange(old, value)),
31 AtomicOp::CompareExchange => atomic_compare_exchange(old, expected, value),
32 _ => Err(Error::interp(format!(
33 "unsupported atomic op `{op:?}` reached the reference interpreter. Fix: define sequential semantics before constructing this AtomicOp."
34 ))),
35 }
36}
37
38pub fn atomic_add(old: u32, value: u32) -> (u32, u32) {
40 (old, old.wrapping_add(value))
41}
42
43pub fn atomic_or(old: u32, value: u32) -> (u32, u32) {
45 (old, old | value)
46}
47
48pub fn atomic_and(old: u32, value: u32) -> (u32, u32) {
50 (old, old & value)
51}
52
53pub fn atomic_xor(old: u32, value: u32) -> (u32, u32) {
55 (old, old ^ value)
56}
57
58pub fn atomic_min(old: u32, value: u32) -> (u32, u32) {
60 (old, old.min(value))
61}
62
63pub fn atomic_max(old: u32, value: u32) -> (u32, u32) {
65 (old, old.max(value))
66}
67
68pub fn atomic_exchange(old: u32, value: u32) -> (u32, u32) {
70 (old, value)
71}
72
73pub fn atomic_compare_exchange(
79 old: u32,
80 expected: Option<u32>,
81 value: u32,
82) -> Result<(u32, u32), vyre::Error> {
83 let Some(expected) = expected else {
84 return Err(Error::interp(
85 "compare-exchange atomic is missing expected value. Fix: set Expr::Atomic.expected.",
86 ));
87 };
88 let new = if old == expected { value } else { old };
89 Ok((old, new))
90}