{- | Module : Numeric.QD.FPU.Unsafe Copyright : (c) Claude Heiland-Allen 2011 License : BSD3 Maintainer : claudiusmaximus@goto10.org Stability : unstable Portability : portable Unsafe FPU manipulation functions. -} module Numeric.QD.FPU.Unsafe ( unsafePreservingFPU ) where import Foreign.Marshal.Alloc (alloca) import Control.Exception (bracket_) import Numeric.QD.FPU.Raw.Unsafe (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 - this 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