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 AtomicOp::LruUpdate => Ok(atomic_lru_update(old, value)),
33 _ => Err(Error::interp(format!(
34 "unsupported atomic op `{op:?}` reached the reference interpreter. Fix: define sequential semantics before constructing this AtomicOp."
35 ))),
36 }
37}
38
39pub fn atomic_add(old: u32, value: u32) -> (u32, u32) {
41 (old, old.wrapping_add(value))
42}
43
44pub fn atomic_or(old: u32, value: u32) -> (u32, u32) {
46 (old, old | value)
47}
48
49pub fn atomic_and(old: u32, value: u32) -> (u32, u32) {
51 (old, old & value)
52}
53
54pub fn atomic_xor(old: u32, value: u32) -> (u32, u32) {
56 (old, old ^ value)
57}
58
59pub fn atomic_min(old: u32, value: u32) -> (u32, u32) {
61 (old, old.min(value))
62}
63
64pub fn atomic_max(old: u32, value: u32) -> (u32, u32) {
66 (old, old.max(value))
67}
68
69pub fn atomic_exchange(old: u32, value: u32) -> (u32, u32) {
71 (old, value)
72}
73
74pub fn atomic_lru_update(old: u32, value: u32) -> (u32, u32) {
81 (old, old.max(value))
82}
83
84pub fn atomic_compare_exchange(
90 old: u32,
91 expected: Option<u32>,
92 value: u32,
93) -> Result<(u32, u32), vyre::Error> {
94 let Some(expected) = expected else {
95 return Err(Error::interp(
96 "compare-exchange atomic is missing expected value. Fix: set Expr::Atomic.expected.",
97 ));
98 };
99 let new = if old == expected { value } else { old };
100 Ok((old, new))
101}