Skip to content

Commit

Permalink
Polyfill around rust floating point handling.
Browse files Browse the repository at this point in the history
  • Loading branch information
davidv1992 authored and folkertdev committed Dec 21, 2023
1 parent 354486e commit 0fb10c2
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 15 deletions.
6 changes: 4 additions & 2 deletions statime/src/filters/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
use fixed::traits::LossyInto;

use super::{Filter, FilterUpdate};
#[allow(unused_imports)]
use crate::float_polyfill::FloatPolyfill;
use crate::{
port::Measurement,
time::{Duration, Time},
Expand Down Expand Up @@ -95,12 +97,12 @@ impl Filter for BasicFilter {

// get relative frequency difference
let mut freq_diff = interval_local / interval_master;
if libm::fabs(freq_diff - 1.0) > self.freq_confidence {
if (freq_diff - 1.0).abs() > self.freq_confidence {
freq_diff = freq_diff.clamp(1.0 - self.freq_confidence, 1.0 + self.freq_confidence);
self.freq_confidence *= 2.0;
} else {
self.freq_confidence -=
(self.freq_confidence - libm::fabs(freq_diff - 1.0)) * self.gain;
(self.freq_confidence - (freq_diff - 1.0).abs()) * self.gain;
}

// and decide the correction (and convert to ppm)
Expand Down
2 changes: 2 additions & 0 deletions statime/src/filters/kalman.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use super::matrix::{Matrix, Vector};
#[allow(unused_imports)]
use crate::float_polyfill::FloatPolyfill;
use crate::{
filters::Filter,
port::Measurement,
Expand Down
45 changes: 45 additions & 0 deletions statime/src/float_polyfill.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
pub(crate) trait FloatPolyfill {
#[cfg(not(feature = "std"))]
fn abs(self) -> Self;
#[cfg(not(feature = "std"))]
fn signum(self) -> Self;
#[cfg(not(feature = "std"))]
fn sqrt(self) -> Self;
#[cfg(not(feature = "std"))]
fn powi(self, n: i32) -> Self;
#[cfg(not(feature = "std"))]
fn exp(self) -> Self;
}

impl FloatPolyfill for f64 {
#[cfg(not(feature = "std"))]
fn abs(self) -> Self {
libm::fabs(self)
}

#[cfg(not(feature = "std"))]
fn signum(self) -> Self {
if self < 0.0 {
-1.0
} else if self > 0.0 {
1.0
} else {
0.0
}
}

#[cfg(not(feature = "std"))]
fn sqrt(self) -> Self {
libm::sqrt(self)
}

#[cfg(not(feature = "std"))]
fn powi(self, n: i32) -> Self {
libm::pow(self, n as f64)
}

#[cfg(not(feature = "std"))]
fn exp(self) -> Self {
libm::exp(self)
}
}
1 change: 1 addition & 0 deletions statime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ mod clock;
pub mod config;
pub(crate) mod datastructures;
pub mod filters;
mod float_polyfill;
pub mod port;
mod ptp_instance;
pub mod time;
Expand Down
8 changes: 2 additions & 6 deletions statime/src/ptp_instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use core::{
use atomic_refcell::AtomicRefCell;
use rand::Rng;

#[allow(unused_imports)]
use crate::float_polyfill::FloatPolyfill;
use crate::{
bmc::{acceptable_master::AcceptableMasterList, bmca::Bmca},
clock::Clock,
Expand Down Expand Up @@ -206,21 +208,15 @@ impl<F: Filter> PtpInstance<F> {
self.state.borrow_mut().bmca(
ports,
Duration::from_seconds(
#[cfg(feature = "std")]
2f64.powi(self.log_bmca_interval.load(Ordering::Relaxed) as i32),
#[cfg(not(feature = "std"))]
libm::pow(2f64, self.log_bmca_interval.load(Ordering::Relaxed) as f64),
),
)
}

/// Time to wait between calls to [`PtpInstance::bmca`]
pub fn bmca_interval(&self) -> core::time::Duration {
core::time::Duration::from_secs_f64(
#[cfg(feature = "std")]
2f64.powi(self.log_bmca_interval.load(Ordering::Relaxed) as i32),
#[cfg(not(feature = "std"))]
libm::pow(2f64, self.log_bmca_interval.load(Ordering::Relaxed) as f64),
)
}
}
4 changes: 3 additions & 1 deletion statime/src/time/duration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ use fixed::{

use super::Interval;
use crate::datastructures::common::TimeInterval;
#[allow(unused_imports)]
use crate::float_polyfill::FloatPolyfill;

/// A duration is a span of time that can also be negative.
///
Expand Down Expand Up @@ -93,7 +95,7 @@ impl Duration {

/// Converts a log interval (as defined by the PTP spec) to a duration
pub fn from_log_interval(log_interval: i8) -> Self {
let seconds = libm::pow(2.0f64, log_interval as f64);
let seconds = 2.0f64.powi(log_interval as i32);
let nanos = seconds * 1_000_000_000.0;
Self::from_fixed_nanos(nanos)
}
Expand Down
9 changes: 3 additions & 6 deletions statime/src/time/interval.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#[allow(unused_imports)]
use crate::float_polyfill::FloatPolyfill;

/// A log2 representation of seconds used to describe the pacing of events in
/// PTP
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
Expand Down Expand Up @@ -69,12 +72,6 @@ impl Interval {
core::time::Duration::from_secs_f64(self.seconds())
}

#[cfg(not(feature = "std"))]
fn as_f64(self) -> f64 {
libm::pow(2.0f64, self.0 as f64)
}

#[cfg(feature = "std")]
fn as_f64(self) -> f64 {
2.0f64.powi(self.0 as i32)
}
Expand Down

0 comments on commit 0fb10c2

Please sign in to comment.