134 lines
2.9 KiB
Rust
134 lines
2.9 KiB
Rust
use core::sync::atomic::{AtomicU32, AtomicU64, Ordering};
|
|
|
|
pub mod containers;
|
|
pub mod error;
|
|
pub mod hash;
|
|
pub mod interval;
|
|
pub mod math;
|
|
pub mod mesh;
|
|
pub mod noise;
|
|
pub mod ptr;
|
|
pub mod quaternion;
|
|
pub mod rng;
|
|
pub mod sampling;
|
|
pub mod sobol;
|
|
pub mod splines;
|
|
pub mod transform;
|
|
|
|
pub use ptr::{DevicePtr, Ptr};
|
|
pub use transform::{AnimatedTransform, Transform, TransformGeneric};
|
|
|
|
#[inline]
|
|
pub fn find_interval<F>(sz: u32, pred: F) -> u32
|
|
where
|
|
F: Fn(u32) -> bool,
|
|
{
|
|
let mut first = 0;
|
|
let mut len = sz;
|
|
|
|
while len > 0 {
|
|
let half = len >> 1;
|
|
let middle = first + half;
|
|
|
|
if pred(middle) {
|
|
first = middle + 1;
|
|
len -= half + 1;
|
|
} else {
|
|
len = half;
|
|
}
|
|
}
|
|
|
|
let ret = (first as i32 - 1).max(0) as u32;
|
|
ret.min(sz.saturating_sub(2))
|
|
}
|
|
|
|
#[inline]
|
|
pub fn partition_slice<T, F>(data: &mut [T], predicate: F) -> usize
|
|
where
|
|
F: Fn(&T) -> bool,
|
|
{
|
|
let mut i = 0;
|
|
for j in 0..data.len() {
|
|
if predicate(&data[j]) {
|
|
data.swap(i, j);
|
|
i += 1;
|
|
}
|
|
}
|
|
i
|
|
}
|
|
|
|
pub struct AtomicFloat {
|
|
bits: AtomicU32,
|
|
}
|
|
|
|
impl AtomicFloat {
|
|
pub fn new(val: f32) -> Self {
|
|
Self {
|
|
bits: AtomicU32::new(val.to_bits()),
|
|
}
|
|
}
|
|
|
|
pub fn get(&self) -> f32 {
|
|
f32::from_bits(self.bits.load(Ordering::Relaxed))
|
|
}
|
|
|
|
pub fn set(&self, val: f32) {
|
|
self.bits.store(val.to_bits(), Ordering::Relaxed);
|
|
}
|
|
|
|
/// Atomically adds `val` to the current value.
|
|
/// Uses a Compare-And-Swap (CAS) loop.
|
|
pub fn add(&self, val: f32) {
|
|
let mut current_bits = self.bits.load(Ordering::Relaxed);
|
|
loop {
|
|
let current_val = f32::from_bits(current_bits);
|
|
let new_val = current_val + val;
|
|
let new_bits = new_val.to_bits();
|
|
|
|
match self.bits.compare_exchange_weak(
|
|
current_bits,
|
|
new_bits,
|
|
Ordering::Relaxed,
|
|
Ordering::Relaxed,
|
|
) {
|
|
Ok(_) => break,
|
|
Err(x) => current_bits = x,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct AtomicDouble {
|
|
bits: AtomicU64,
|
|
}
|
|
|
|
impl AtomicDouble {
|
|
pub fn new(val: f64) -> Self {
|
|
Self {
|
|
bits: AtomicU64::new(val.to_bits()),
|
|
}
|
|
}
|
|
|
|
pub fn get(&self) -> f64 {
|
|
f64::from_bits(self.bits.load(Ordering::Relaxed))
|
|
}
|
|
|
|
pub fn add(&self, val: f64) {
|
|
let mut current_bits = self.bits.load(Ordering::Relaxed);
|
|
loop {
|
|
let current_val = f64::from_bits(current_bits);
|
|
let new_val = current_val + val;
|
|
let new_bits = new_val.to_bits();
|
|
|
|
match self.bits.compare_exchange_weak(
|
|
current_bits,
|
|
new_bits,
|
|
Ordering::Relaxed,
|
|
Ordering::Relaxed,
|
|
) {
|
|
Ok(_) => break,
|
|
Err(x) => current_bits = x,
|
|
}
|
|
}
|
|
}
|
|
}
|