Skip to content

Commit

Permalink
*: impl Atomic for f32
Browse files Browse the repository at this point in the history
Signed-off-by: sh0rez <me@shorez.de>
  • Loading branch information
sh0rez committed Feb 4, 2022
1 parent e6db79e commit 26522dc
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 61 deletions.
7 changes: 7 additions & 0 deletions src/encoding/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ impl Encode for f64 {
}
}

impl Encode for f32 {
fn encode(&self, writer: &mut dyn Write) -> Result<(), std::io::Error> {
writer.write_all(dtoa::Buffer::new().format(*self).as_bytes())?;
Ok(())
}
}

impl Encode for u64 {
fn encode(&self, writer: &mut dyn Write) -> Result<(), std::io::Error> {
writer.write_all(itoa::Buffer::new().format(*self).as_bytes())?;
Expand Down
55 changes: 34 additions & 21 deletions src/metrics/counter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,31 +134,44 @@ impl Atomic<u32> for AtomicU32 {
}
}

#[cfg(not(any(target_arch = "mips", target_arch = "powerpc")))]
impl Atomic<f64> for AtomicU64 {
fn inc(&self) -> f64 {
self.inc_by(1.0)
}
macro_rules! atomic_float {
($F:ty, $A:ty) => {
impl Atomic<$F> for $A {
fn inc(&self) -> $F {
self.inc_by(1.0)
}

fn inc_by(&self, v: f64) -> f64 {
let mut old_u64 = self.load(Ordering::Relaxed);
let mut old_f64;
loop {
old_f64 = f64::from_bits(old_u64);
let new = f64::to_bits(old_f64 + v);
match self.compare_exchange_weak(old_u64, new, Ordering::Relaxed, Ordering::Relaxed) {
Ok(_) => break,
Err(x) => old_u64 = x,
fn inc_by(&self, v: $F) -> $F {
let mut old_atom = self.load(Ordering::Relaxed);
let mut old_flt;
loop {
old_flt = <$F>::from_bits(old_atom);
let new = <$F>::to_bits(old_flt + v);
match self.compare_exchange_weak(
old_atom,
new,
Ordering::Relaxed,
Ordering::Relaxed,
) {
Ok(_) => break,
Err(x) => old_atom = x,
}
}

old_flt
}

fn get(&self) -> $F {
<$F>::from_bits(self.load(Ordering::Relaxed))
}
}
};
}

old_f64
}
#[cfg(not(any(target_arch = "mips", target_arch = "powerpc", target_arch = "xtensa")))]
atomic_float!(f64, AtomicU64);

fn get(&self) -> f64 {
f64::from_bits(self.load(Ordering::Relaxed))
}
}
atomic_float!(f32, AtomicU32);

impl<N, A> TypedMetric for Counter<N, A> {
const TYPE: MetricType = MetricType::Counter;
Expand All @@ -176,7 +189,7 @@ mod tests {
assert_eq!(1, counter.get());
}

#[cfg(not(any(target_arch = "mips", target_arch = "powerpc")))]
#[cfg(not(any(target_arch = "mips", target_arch = "powerpc", target_arch = "xtensa")))]
#[test]
fn f64_stored_in_atomic_u64() {
fn prop(fs: Vec<f64>) {
Expand Down
98 changes: 58 additions & 40 deletions src/metrics/gauge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,55 +175,73 @@ impl Atomic<u32> for AtomicU32 {
}
}

#[cfg(not(any(target_arch = "mips", target_arch = "powerpc")))]
impl Atomic<f64> for AtomicU64 {
fn inc(&self) -> f64 {
self.inc_by(1.0)
}

fn inc_by(&self, v: f64) -> f64 {
let mut old_u64 = self.load(Ordering::Relaxed);
let mut old_f64;
loop {
old_f64 = f64::from_bits(old_u64);
let new = f64::to_bits(old_f64 + v);
match self.compare_exchange_weak(old_u64, new, Ordering::Relaxed, Ordering::Relaxed) {
Ok(_) => break,
Err(x) => old_u64 = x,
macro_rules! atomic_float {
($F:ty, $A:ty) => {
impl Atomic<$F> for $A {
fn inc(&self) -> $F {
self.inc_by(1.0)
}
}

old_f64
}

fn dec(&self) -> f64 {
self.dec_by(1.0)
}
fn inc_by(&self, v: $F) -> $F {
let mut old_atom = self.load(Ordering::Relaxed);
let mut old_flt;
loop {
old_flt = <$F>::from_bits(old_atom);
let new = <$F>::to_bits(old_flt + v);
match self.compare_exchange_weak(
old_atom,
new,
Ordering::Relaxed,
Ordering::Relaxed,
) {
Ok(_) => break,
Err(x) => old_atom = x,
}
}

old_flt
}

fn dec_by(&self, v: f64) -> f64 {
let mut old_u64 = self.load(Ordering::Relaxed);
let mut old_f64;
loop {
old_f64 = f64::from_bits(old_u64);
let new = f64::to_bits(old_f64 - v);
match self.compare_exchange_weak(old_u64, new, Ordering::Relaxed, Ordering::Relaxed) {
Ok(_) => break,
Err(x) => old_u64 = x,
fn dec(&self) -> $F {
self.dec_by(1.0)
}
}

old_f64
}
fn dec_by(&self, v: $F) -> $F {
let mut old_atom = self.load(Ordering::Relaxed);
let mut old_flt;
loop {
old_flt = <$F>::from_bits(old_atom);
let new = <$F>::to_bits(old_flt - v);
match self.compare_exchange_weak(
old_atom,
new,
Ordering::Relaxed,
Ordering::Relaxed,
) {
Ok(_) => break,
Err(x) => old_atom = x,
}
}

old_flt
}

fn set(&self, v: f64) -> f64 {
f64::from_bits(self.swap(f64::to_bits(v), Ordering::Relaxed))
}
fn set(&self, v: $F) -> $F {
<$F>::from_bits(self.swap(<$F>::to_bits(v), Ordering::Relaxed))
}

fn get(&self) -> f64 {
f64::from_bits(self.load(Ordering::Relaxed))
}
fn get(&self) -> $F {
<$F>::from_bits(self.load(Ordering::Relaxed))
}
}
};
}

#[cfg(not(any(target_arch = "mips", target_arch = "powerpc", target_arch = "xtensa")))]
atomic_float!(f64, AtomicU64);

atomic_float!(f32, AtomicU32);

impl<N, A> TypedMetric for Gauge<N, A> {
const TYPE: MetricType = MetricType::Gauge;
}
Expand Down

0 comments on commit 26522dc

Please sign in to comment.