From 94993901cdb75fad7b68080eaa0e9b546810a107 Mon Sep 17 00:00:00 2001 From: Terence Date: Tue, 1 Jun 2021 20:41:38 -0400 Subject: wip --- src/utils.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'src/utils.rs') diff --git a/src/utils.rs b/src/utils.rs index c1eb31d..4ea2339 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -4,6 +4,7 @@ use na::{Matrix3, Point2, Point3, Scalar, SimdRealField, Vector2, Vector3}; use num::Zero; use simba::simd::SimdValue; use std::ops::IndexMut; +use std::os::raw::c_int; use parry::utils::SdpMatrix3; use { @@ -670,6 +671,48 @@ impl Drop for FlushToZeroDenormalsAreZeroFlags { } } +// This is an RAII structure that disables floating point exceptions while +// it is alive, so that operations which generate NaNs and infinite values +// intentionally will not trip an exception when debugging problematic +// code that is generating NaNs and infinite values erroneously. +#[derive(Clone, Debug, PartialEq, Eq)] +pub(crate) struct DisableFloatingPointExceptionsFlags { + original_flags: c_int, +} + +#[cfg(feature = "avoid-fe-exceptions")] +extern "C" { + fn feenableexcept(flags: c_int); + fn fecleareexcept(flags: c_int); + fn fetestexcept(flags: c_int) -> c_int; + static FE_ALL_EXCEPT: c_int; +} + +impl DisableFloatingPointExceptionsFlags { + #[cfg(not(feature = "avoid-fe-exceptions"))] + pub fn disable_floating_point_exceptions() -> Self { + Self { original_flags: 0 } + } + + #[cfg(feature = "avoid-fe-exceptions")] + pub fn disable_floating_point_exceptions() -> Self { + unsafe { + let original_flags = fetestexcept(FE_ALL_EXCEPT); + fecleareexcept(FE_ALL_EXCEPT); + Self { original_flags } + } + } +} + +#[cfg(feature = "avoid-fe-exceptions")] +impl Drop for DisableFloatingPointExceptionsFlags { + fn drop(&mut self) { + unsafe { + feenableexcept(self.original_flags); + } + } +} + pub(crate) fn select_other(pair: (T, T), elt: T) -> T { if pair.0 == elt { pair.1 -- cgit From 16fd97595d54adbe715d2059a115ae904531f553 Mon Sep 17 00:00:00 2001 From: Terence Date: Tue, 1 Jun 2021 21:27:51 -0400 Subject: wee --- src/utils.rs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'src/utils.rs') diff --git a/src/utils.rs b/src/utils.rs index 4ea2339..4602142 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -677,28 +677,32 @@ impl Drop for FlushToZeroDenormalsAreZeroFlags { // code that is generating NaNs and infinite values erroneously. #[derive(Clone, Debug, PartialEq, Eq)] pub(crate) struct DisableFloatingPointExceptionsFlags { - original_flags: c_int, + #[cfg(feature = "avoid-fe-exceptions")] + // We can't get a precise size for this, because it's of type + // `fenv_t`, which is a definition that doesn't exist in rust + // (not even in the libc crate, as of the time of writing.) + // But since the state is intended to be stored on the stack, + // 256 bytes should be more than enough. + original_flags: [u8; 256], } #[cfg(feature = "avoid-fe-exceptions")] extern "C" { - fn feenableexcept(flags: c_int); - fn fecleareexcept(flags: c_int); - fn fetestexcept(flags: c_int) -> c_int; - static FE_ALL_EXCEPT: c_int; + fn feholdexcept(env: *mut std::ffi::c_void); + fn fesetenv(env: *const std::ffi::c_void); } impl DisableFloatingPointExceptionsFlags { #[cfg(not(feature = "avoid-fe-exceptions"))] pub fn disable_floating_point_exceptions() -> Self { - Self { original_flags: 0 } + Self { } } #[cfg(feature = "avoid-fe-exceptions")] pub fn disable_floating_point_exceptions() -> Self { unsafe { - let original_flags = fetestexcept(FE_ALL_EXCEPT); - fecleareexcept(FE_ALL_EXCEPT); + let mut original_flags = [0; 256]; + feholdexcept(original_flags.as_mut_ptr() as *mut _); Self { original_flags } } } @@ -708,7 +712,7 @@ impl DisableFloatingPointExceptionsFlags { impl Drop for DisableFloatingPointExceptionsFlags { fn drop(&mut self) { unsafe { - feenableexcept(self.original_flags); + fesetenv(self.original_flags.as_ptr() as *const _); } } } -- cgit From 6356dca1d5a753768bbb479aa9491805223e1c60 Mon Sep 17 00:00:00 2001 From: Terence Date: Tue, 1 Jun 2021 21:35:29 -0400 Subject: remove c_int --- src/utils.rs | 1 - 1 file changed, 1 deletion(-) (limited to 'src/utils.rs') diff --git a/src/utils.rs b/src/utils.rs index 4602142..84ed250 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -4,7 +4,6 @@ use na::{Matrix3, Point2, Point3, Scalar, SimdRealField, Vector2, Vector3}; use num::Zero; use simba::simd::SimdValue; use std::ops::IndexMut; -use std::os::raw::c_int; use parry::utils::SdpMatrix3; use { -- cgit