, throwTo -- :: ThreadId -> Exception -> IO ()
, par -- :: a -> b -> b
, pseq -- :: a -> b -> b
+ , runSparks
, yield -- :: IO ()
, labelThread -- :: ThreadId -> String -> IO ()
, newTVar -- :: a -> STM (TVar a)
, newTVarIO -- :: a -> STM (TVar a)
, readTVar -- :: TVar a -> STM a
+ , readTVarIO -- :: TVar a -> IO a
, writeTVar -- :: a -> TVar a -> STM ()
, unsafeIOToSTM -- :: IO a -> STM a
GHC note: the new thread inherits the /blocked/ state of the parent
(see 'Control.Exception.block').
+
+The newly created thread has an exception handler that discards the
+exceptions 'BlockedOnDeadMVar', 'BlockedIndefinitely', and
+'ThreadKilled', and passes all other exceptions to the uncaught
+exception handler (see 'setUncaughtExceptionHandler').
-}
forkIO :: IO () -> IO ThreadId
forkIO action = IO $ \ s ->
n <- peek n_capabilities
return (fromIntegral n)
+#if defined(mingw32_HOST_OS) && defined(__PIC__)
+foreign import ccall "_imp__n_capabilities" n_capabilities :: Ptr CInt
+#else
foreign import ccall "&n_capabilities" n_capabilities :: Ptr CInt
-
+#endif
childHandler :: SomeException -> IO ()
childHandler err = catchException (real_handler err) childHandler
> killThread tid = throwTo tid ThreadKilled
+Killthread is a no-op if the target thread has already completed.
-}
killThread :: ThreadId -> IO ()
killThread tid = throwTo tid ThreadKilled
(<http://research.microsoft.com/~simonpj/Papers/asynch-exns.htm>).
In the paper, 'throwTo' is non-blocking; but the library implementation adopts
a more synchronous design in which 'throwTo' does not return until the exception
-is received by the target thread. The trade-off is discussed in Section 8 of the paper.
-Like any blocking operation, 'throwTo' is therefore interruptible (see Section 4.3 of
+is received by the target thread. The trade-off is discussed in Section 9 of the paper.
+Like any blocking operation, 'throwTo' is therefore interruptible (see Section 5.3 of
the paper).
There is currently no guarantee that the exception delivered by 'throwTo' will be
-delivered at the first possible opportunity. In particular, if a thread may
+delivered at the first possible opportunity. In particular, a thread may
unblock and then re-block exceptions (using 'unblock' and 'block') without receiving
a pending 'throwTo'. This is arguably undesirable behaviour.
par :: a -> b -> b
par x y = case (par# x) of { _ -> lazy y }
+-- | Internal function used by the RTS to run sparks.
+runSparks :: IO ()
+runSparks = IO loop
+ where loop s = case getSpark# s of
+ (# s', n, p #) ->
+ if n ==# 0# then (# s', () #)
+ else p `seq` loop s'
data BlockReason
= BlockedOnMVar
case newTVar# val s1# of
(# s2#, tvar# #) -> (# s2#, TVar tvar# #)
+-- |Return the current value stored in a TVar.
+-- This is equivalent to
+--
+-- > readTVarIO = atomically . readTVar
+--
+-- but works much faster, because it doesn't perform a complete
+-- transaction, it just reads the current value of the 'TVar'.
+readTVarIO :: TVar a -> IO a
+readTVarIO (TVar tvar#) = IO $ \s# -> readTVarIO# tvar# s#
+
-- |Return the current value stored in a TVar
readTVar :: TVar a -> STM a
readTVar (TVar tvar#) = STM $ \s# -> readTVar# tvar# s#