qd-1.0: Numeric/QD/FPU/Unsafe.hs
{- |
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