X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=GHC%2FConc.lhs;h=e52785fc7d17441c837947942ec4cfede0a1d603;hb=b66a730b881d05c34c0dfe2da052b5fa01429244;hp=bd0329532465d2f8e2facee6a1add7597f5e941a;hpb=4ff009b65beefe01fe812a68f60269279bdc056e;p=haskell-directory.git diff --git a/GHC/Conc.lhs b/GHC/Conc.lhs index bd03295..e52785f 100644 --- a/GHC/Conc.lhs +++ b/GHC/Conc.lhs @@ -98,7 +98,7 @@ import Data.Maybe import GHC.Base import GHC.IOBase import GHC.Num ( Num(..) ) -import GHC.Real ( fromIntegral, quot ) +import GHC.Real ( fromIntegral, div ) #ifndef mingw32_HOST_OS import GHC.Base ( Int(..) ) #endif @@ -707,8 +707,8 @@ data IOReq #endif data DelayReq - = Delay {-# UNPACK #-} !Word64 {-# UNPACK #-} !(MVar ()) - | DelaySTM {-# UNPACK #-} !Word64 {-# UNPACK #-} !(TVar Bool) + = Delay {-# UNPACK #-} !USecs {-# UNPACK #-} !(MVar ()) + | DelaySTM {-# UNPACK #-} !USecs {-# UNPACK #-} !(TVar Bool) #ifndef mingw32_HOST_OS pendingEvents :: IORef [IOReq] @@ -736,6 +736,7 @@ insertDelay d1 ds@(d2 : rest) | delayTime d1 <= delayTime d2 = d1 : ds | otherwise = d2 : insertDelay d1 rest +delayTime :: DelayReq -> USecs delayTime (Delay t _) = t delayTime (DelaySTM t _) = t @@ -748,6 +749,15 @@ atomicModifyIORef (IORef (STRef r#)) f = IO $ \s -> atomicModifyMutVar# r# f s foreign import ccall unsafe "getUSecOfDay" getUSecOfDay :: IO USecs +prodding :: IORef Bool +{-# NOINLINE prodding #-} +prodding = unsafePerformIO (newIORef False) + +prodServiceThread :: IO () +prodServiceThread = do + was_set <- atomicModifyIORef prodding (\a -> (True,a)) + if (not (was_set)) then wakeupIOManager else return () + #ifdef mingw32_HOST_OS -- ---------------------------------------------------------------------------- -- Windows IO manager thread @@ -788,8 +798,7 @@ service_loop wakeup old_delays = do _other -> service_cont wakeup delays' -- probably timeout service_cont wakeup delays = do - takeMVar prodding - putMVar prodding False + atomicModifyIORef prodding (\_ -> (False,False)) service_loop wakeup delays -- must agree with rts/win32/ThrIOManager.c @@ -809,18 +818,9 @@ stick :: IORef HANDLE {-# NOINLINE stick #-} stick = unsafePerformIO (newIORef nullPtr) -prodding :: MVar Bool -{-# NOINLINE prodding #-} -prodding = unsafePerformIO (newMVar False) - -prodServiceThread :: IO () -prodServiceThread = do - b <- takeMVar prodding - if (not b) - then do hdl <- readIORef stick - c_sendIOManagerEvent io_MANAGER_WAKEUP - else return () - putMVar prodding True +wakeupIOManager = do + hdl <- readIORef stick + c_sendIOManagerEvent io_MANAGER_WAKEUP -- Walk the queue of pending delays, waking up any that have passed -- and return the smallest delay to wait for. The queue of pending @@ -836,9 +836,10 @@ getDelay now all@(d : rest) atomically $ writeTVar t True getDelay now rest _otherwise -> - return (all, (fromIntegral (delayTime d - now) * - fromIntegral tick_msecs)) - -- delay is in millisecs for WaitForSingleObject + -- delay is in millisecs for WaitForSingleObject + let micro_seconds = delayTime d - now + milli_seconds = (micro_seconds + 999) `div` 1000 + in return (all, fromIntegral milli_seconds) -- ToDo: this just duplicates part of System.Win32.Types, which isn't -- available yet. We should move some Win32 functionality down here, @@ -952,8 +953,7 @@ service_loop wakeup readfds writefds ptimeval old_reqs old_delays = do if exit then return () else do - takeMVar prodding - putMVar prodding False + atomicModifyIORef prodding (\_ -> (False,False)) reqs' <- if wakeup_all then do wakeupAll reqs; return [] else completeRequests reqs readfds writefds [] @@ -967,19 +967,11 @@ stick :: IORef Fd {-# NOINLINE stick #-} stick = unsafePerformIO (newIORef 0) -prodding :: MVar Bool -{-# NOINLINE prodding #-} -prodding = unsafePerformIO (newMVar False) - -prodServiceThread :: IO () -prodServiceThread = do - b <- takeMVar prodding - if (not b) - then do fd <- readIORef stick - with io_MANAGER_WAKEUP $ \pbuf -> do - c_write (fromIntegral fd) pbuf 1; return () - else return () - putMVar prodding True +wakeupIOManager :: IO () +wakeupIOManager = do + fd <- readIORef stick + with io_MANAGER_WAKEUP $ \pbuf -> do + c_write (fromIntegral fd) pbuf 1; return () foreign import ccall "&signal_handlers" handlers :: Ptr (Ptr (StablePtr (IO ())))