module Numeric.QD.FPU ( unsafePreservingFPU ) where import Foreign.Marshal.Alloc (alloca) import Control.Exception (bracket_) import Numeric.QD.FPU.Raw (fpu_fix_start, fpu_fix_end) -- |@'unsafePreservingFPU' f@ executes the computation @f@, ensuring -- that the FPU control words are set to avoid problems from excess -- precision. See the libqd documentation for further details. -- -- This function is unsafe in a threaded runtime as Haskell threads can -- migrate between OS threads, moreover there is no checking for nested -- calls which results in race conditions. -- -- Some steps can be taken to mitigate some of this badness; perhaps -- using (for example) @'GHC.Conc.forkOnIO'@ might help. unsafePreservingFPU :: IO a -> IO a unsafePreservingFPU f = alloca $ \p -> bracket_ (fpu_fix_start p) (fpu_fix_end p) f