Skip to content

Commit

Permalink
std/sync/atomic: rehandle atomics
Browse files Browse the repository at this point in the history
  • Loading branch information
mertcandav committed Jan 18, 2025
1 parent e9d85e7 commit f1fe418
Show file tree
Hide file tree
Showing 2 changed files with 344 additions and 52 deletions.
49 changes: 41 additions & 8 deletions std/runtime/atomic.jule
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,44 @@ cpp unsafe fn __atomic_fetch_add[T](*unsafe, T, atomicMemoryOrder): T

// Atomically stores new value to p with memory order mo, and returns the old value.
fn atomicSwap[T](mut &p: T, new: T, mo: atomicMemoryOrder): (old: T) {
let mut tmp: T
unsafe { cpp.__atomic_exchange[T](&p, &new, &tmp, mo) }
ret tmp
ret atomicSwapZ(p, new, mo)
}

// Atomically reads value of the p with memory order mo and returns.
fn atomicLoad[T](&p: T, mo: atomicMemoryOrder): T {
let mut tmp: T
ret atomicLoadZ[T, T](p, mo)
}

// Atomically reads value of the p and compares it with old.
// If comparison results with true, it atomically stores new value into p.
// In every case, it will use memory order mo.
// Reports whether swap succeeded.
fn atomicCompareAndSwap[T](mut &p: T, old: T, new: T, mo: atomicMemoryOrder): (swapped: bool) {
ret atomicCompareAndSwapZ(p, old, new, mo)
}

// Atomically adds delta to p with memory order mo and returns the new value.
fn atomicAdd[T](mut &p: T, delta: T, mo: atomicMemoryOrder): (new: T) {
ret atomicAddZ(p, delta, mo)
}

// Atomically stores new value to p with memory order mo.
fn atomicStore[T](mut &p: T, val: T, mo: atomicMemoryOrder) {
atomicStoreZ(p, val, mo)
}

// Atomically stores new value to p with memory order mo, and returns the old value.
// T1 is a base pointer type, T2 is the output type.
fn atomicSwapZ[T1, T2](mut &p: T1, new: T2, mo: atomicMemoryOrder): (old: T2) {
let mut tmp: T2
unsafe { cpp.__atomic_exchange[T2](&p, &new, &tmp, mo) }
ret tmp
}

// Atomically reads value of the p with memory order mo and returns.
// T1 is a base pointer type, T2 is the output type.
fn atomicLoadZ[T1, T2](&p: T1, mo: atomicMemoryOrder): T2 {
let mut tmp: T2
unsafe { cpp.__atomic_load(&p, &tmp, mo) }
ret tmp
}
Expand All @@ -44,17 +74,20 @@ fn atomicLoad[T](&p: T, mo: atomicMemoryOrder): T {
// If comparison results with true, it atomically stores new value into p.
// In every case, it will use memory order mo.
// Reports whether swap succeeded.
fn atomicCompareAndSwap[T](mut &p: T, old: T, new: T, mo: atomicMemoryOrder): (swapped: bool) {
// T1 is a base pointer type, T2 is the output type.
fn atomicCompareAndSwapZ[T1, T2](mut &p: T1, old: T2, new: T2, mo: atomicMemoryOrder): (swapped: bool) {
const Strong = 0 // strong atomicity
ret unsafe { cpp.__atomic_compare_exchange(&p, &old, &new, Strong, mo, mo) }
}

// Atomically adds delta to p with memory order mo and returns the new value.
fn atomicAdd[T](mut &p: T, delta: T, mo: atomicMemoryOrder): (new: T) {
ret unsafe { cpp.__atomic_fetch_add[T](&p, delta, mo) } + delta
// T1 is a base pointer type, T2 is the output type.
fn atomicAddZ[T1, T2](mut &p: T1, delta: T2, mo: atomicMemoryOrder): (new: T2) {
ret unsafe { cpp.__atomic_fetch_add[T2](&p, delta, mo) } + delta
}

// Atomically stores new value to p with memory order mo.
fn atomicStore[T](mut &p: T, val: T, mo: atomicMemoryOrder) {
// T1 is a base pointer type, T2 is the output type.
fn atomicStoreZ[T1, T2](mut &p: T1, val: T2, mo: atomicMemoryOrder) {
unsafe { cpp.__atomic_store(&p, &val, mo) }
}
Loading

0 comments on commit f1fe418

Please sign in to comment.