[Git][ghc/ghc][master] Update `Control.Concurrent.*` documentation

Marge Bot (@marge-bot) gitlab at gitlab.haskell.org
Tue Aug 22 16:32:26 UTC 2023



Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC


Commits:
4ba088d1 by konsumlamm at 2023-08-22T12:32:02-04:00
Update `Control.Concurrent.*` documentation

- - - - -


5 changed files:

- libraries/base/Control/Concurrent/Chan.hs
- libraries/base/Control/Concurrent/MVar.hs
- libraries/base/Control/Concurrent/QSem.hs
- libraries/base/Control/Concurrent/QSemN.hs
- libraries/base/GHC/MVar.hs


Changes:

=====================================
libraries/base/Control/Concurrent/Chan.hs
=====================================
@@ -13,9 +13,9 @@
 --
 -- Unbounded channels.
 --
--- The channels are implemented with @MVar at s and therefore inherit all the
+-- The channels are implemented with 'Control.Concurrent.MVar's and therefore inherit all the
 -- caveats that apply to @MVar at s (possibility of races, deadlocks etc). The
--- stm (software transactional memory) library has a more robust implementation
+-- @stm@ (software transactional memory) library has a more robust implementation
 -- of channels called @TChan at s.
 --
 -----------------------------------------------------------------------------
@@ -43,7 +43,7 @@ import Control.Exception (mask_)
 #define _UPK_(x) {-# UNPACK #-} !(x)
 
 -- A channel is represented by two @MVar at s keeping track of the two ends
--- of the channel contents,i.e.,  the read- and write ends. Empty @MVar at s
+-- of the channel contents, i.e., the read- and write ends. Empty @MVar at s
 -- are used to handle consumers trying to read from an empty channel.
 
 -- |'Chan' is an abstract type representing an unbounded FIFO channel.
@@ -59,13 +59,13 @@ data ChItem a = ChItem a _UPK_(Stream a)
   -- although it leads to higher allocation, the channel data takes up
   -- less space and is therefore quicker to GC.
 
--- See the Concurrent Haskell paper for a diagram explaining the
+-- See the Concurrent Haskell paper for a diagram explaining
 -- how the different channel operations proceed.
 
 -- @newChan@ sets up the read and write end of a channel by initialising
 -- these two @MVar at s with an empty @MVar at .
 
--- |Build and returns a new instance of 'Chan'.
+-- |Build and return a new instance of 'Chan'.
 newChan :: IO (Chan a)
 newChan = do
    hole  <- newEmptyMVar
@@ -113,7 +113,7 @@ readChan (Chan readVar _) =
     return (new_read_end, val)
 
 -- |Duplicate a 'Chan': the duplicate channel begins empty, but data written to
--- either channel from then on will be available from both.  Hence this creates
+-- either channel from then on will be available from both. Hence this creates
 -- a kind of broadcast channel, where data written by anyone is seen by
 -- everyone else.
 --


=====================================
libraries/base/Control/Concurrent/MVar.hs
=====================================
@@ -11,7 +11,7 @@
 -- Stability   :  stable
 -- Portability :  non-portable (concurrency)
 --
--- An @'MVar' t@ is mutable location that is either empty or contains a
+-- An @'MVar' t@ is a mutable location that is either empty or contains a
 -- value of type @t at .  It has two fundamental operations: 'putMVar'
 -- which fills an 'MVar' if it is empty and blocks otherwise, and
 -- 'takeMVar' which empties an 'MVar' if it is full and blocks
@@ -25,7 +25,7 @@
 --      wait and signal.
 --
 -- They were introduced in the paper
--- <https://www.haskell.org/ghc/docs/papers/concurrent-haskell.ps.gz "Concurrent Haskell">
+-- ["Concurrent Haskell"](https://www.microsoft.com/en-us/research/wp-content/uploads/1996/01/concurrent-haskell.pdf)
 -- by Simon Peyton Jones, Andrew Gordon and Sigbjorn Finne, though
 -- some details of their implementation have since then changed (in
 -- particular, a put on a full 'MVar' used to error, but now merely
@@ -35,7 +35,7 @@
 --
 -- 'MVar's offer more flexibility than 'Data.IORef.IORef's, but less flexibility
 -- than 'GHC.Conc.STM'.  They are appropriate for building synchronization
--- primitives and performing simple interthread communication; however
+-- primitives and performing simple inter-thread communication; however
 -- they are very simple and susceptible to race conditions, deadlocks or
 -- uncaught exceptions.  Do not use them if you need to perform larger
 -- atomic operations such as reading from multiple variables: use 'GHC.Conc.STM'
@@ -54,8 +54,8 @@
 -- No thread can be blocked indefinitely on an 'MVar' unless another
 -- thread holds that 'MVar' indefinitely.  One usual implementation of
 -- this fairness guarantee is that threads blocked on an 'MVar' are
--- served in a first-in-first-out fashion, but this is not guaranteed
--- in the semantics.
+-- served in a first-in-first-out fashion (this is what GHC does),
+-- but this is not guaranteed in the semantics.
 --
 -- === Gotchas
 --
@@ -64,7 +64,7 @@
 -- 'MVar', it will be evaluated by the thread that consumes it, not the
 -- thread that produced it.  Be sure to 'evaluate' values to be placed
 -- in an 'MVar' to the appropriate normal form, or utilize a strict
--- MVar provided by the strict-concurrency package.
+-- @MVar@ provided by the [strict-concurrency](https://hackage.haskell.org/package/strict-concurrency) package.
 --
 -- === Ordering
 --
@@ -89,33 +89,33 @@
 -- reader has not read yet, and empty otherwise.
 --
 -- @
---     data SkipChan a = SkipChan (MVar (a, [MVar ()])) (MVar ())
+-- data SkipChan a = SkipChan (MVar (a, [MVar ()])) (MVar ())
 --
---     newSkipChan :: IO (SkipChan a)
---     newSkipChan = do
---         sem <- newEmptyMVar
---         main <- newMVar (undefined, [sem])
---         return (SkipChan main sem)
+-- newSkipChan :: IO (SkipChan a)
+-- newSkipChan = do
+--     sem <- newEmptyMVar
+--     main <- newMVar (undefined, [sem])
+--     return (SkipChan main sem)
 --
---     putSkipChan :: SkipChan a -> a -> IO ()
---     putSkipChan (SkipChan main _) v = do
---         (_, sems) <- takeMVar main
---         putMVar main (v, [])
---         mapM_ (\sem -> putMVar sem ()) sems
+-- putSkipChan :: SkipChan a -> a -> IO ()
+-- putSkipChan (SkipChan main _) v = do
+--     (_, sems) <- takeMVar main
+--     putMVar main (v, [])
+--     mapM_ (\\sem -> putMVar sem ()) sems
 --
---     getSkipChan :: SkipChan a -> IO a
---     getSkipChan (SkipChan main sem) = do
---         takeMVar sem
---         (v, sems) <- takeMVar main
---         putMVar main (v, sem:sems)
---         return v
+-- getSkipChan :: SkipChan a -> IO a
+-- getSkipChan (SkipChan main sem) = do
+--     takeMVar sem
+--     (v, sems) <- takeMVar main
+--     putMVar main (v, sem : sems)
+--     return v
 --
---     dupSkipChan :: SkipChan a -> IO (SkipChan a)
---     dupSkipChan (SkipChan main _) = do
---         sem <- newEmptyMVar
---         (v, sems) <- takeMVar main
---         putMVar main (v, sem:sems)
---         return (SkipChan main sem)
+-- dupSkipChan :: SkipChan a -> IO (SkipChan a)
+-- dupSkipChan (SkipChan main _) = do
+--     sem <- newEmptyMVar
+--     (v, sems) <- takeMVar main
+--     putMVar main (v, sem : sems)
+--     return (SkipChan main sem)
 -- @
 --
 -- This example was adapted from the original Concurrent Haskell paper.
@@ -186,7 +186,7 @@ swapMVar mvar new =
 -}
 {-# INLINE withMVar #-}
 -- inlining has been reported to have dramatic effects; see
--- http://www.haskell.org//pipermail/haskell/2006-May/017907.html
+-- https://mail.haskell.org/pipermail/haskell/2006-May/017907.html
 withMVar :: MVar a -> (a -> IO b) -> IO b
 withMVar m io =
   mask $ \restore -> do
@@ -274,7 +274,7 @@ addMVarFinalizer :: MVar a -> IO () -> IO ()
 addMVarFinalizer = GHC.MVar.addMVarFinalizer
 
 -- | Make a 'Weak' pointer to an 'MVar', using the second argument as
--- a finalizer to run when 'MVar' is garbage-collected
+-- a finalizer to run when the 'MVar' is garbage-collected
 --
 -- @since 4.6.0.0
 mkWeakMVar :: MVar a -> IO () -> IO (Weak (MVar a))


=====================================
libraries/base/Control/Concurrent/QSem.hs
=====================================
@@ -34,7 +34,7 @@ import Data.Maybe
 --
 -- The pattern
 --
--- >   bracket_ waitQSem signalQSem (...)
+-- > bracket_ waitQSem signalQSem (...)
 --
 -- is safe; it never loses a unit of the resource.
 --
@@ -67,7 +67,7 @@ newQSem initial
       sem <- newMVar (initial, [], [])
       return (QSem sem)
 
--- |Wait for a unit to become available
+-- |Wait for a unit to become available.
 waitQSem :: QSem -> IO ()
 waitQSem (QSem m) =
   mask_ $ do
@@ -91,7 +91,7 @@ waitQSem (QSem m) =
                             else do putMVar b (); return (i,b1,b2)
                    putMVar m r')
 
--- |Signal that a unit of the 'QSem' is available
+-- |Signal that a unit of the 'QSem' is available.
 signalQSem :: QSem -> IO ()
 signalQSem (QSem m) =
   uninterruptibleMask_ $ do -- Note [signal uninterruptible]


=====================================
libraries/base/Control/Concurrent/QSemN.hs
=====================================
@@ -32,12 +32,12 @@ import Data.IORef (IORef, newIORef, atomicModifyIORef)
 import System.IO.Unsafe (unsafePerformIO)
 
 -- | 'QSemN' is a quantity semaphore in which the resource is acquired
--- and released in units of one. It provides guaranteed FIFO ordering
+-- and released in arbitrary amounts. It provides guaranteed FIFO ordering
 -- for satisfying blocked `waitQSemN` calls.
 --
 -- The pattern
 --
--- >   bracket_ (waitQSemN n) (signalQSemN n) (...)
+-- > bracket_ (waitQSemN n) (signalQSemN n) (...)
 --
 -- is safe; it never loses any of the resource.
 --
@@ -71,7 +71,7 @@ newQSemN initial
 -- An unboxed version of Maybe (MVar a)
 data MaybeMV a = JustMV !(MVar a) | NothingMV
 
--- |Wait for the specified quantity to become available
+-- |Wait for the specified quantity to become available.
 waitQSemN :: QSemN -> Int -> IO ()
 -- We need to mask here. Once we've enqueued our MVar, we need
 -- to be sure to wait for it. Otherwise, we could lose our


=====================================
libraries/base/GHC/MVar.hs
=====================================
@@ -42,9 +42,11 @@ as a box, which may be empty or full.
 -}
 
 -- pull in Eq (Mvar a) too, to avoid GHC.Conc being an orphan-instance module
--- | @since 4.1.0.0
+-- | Compares the underlying pointers.
+--
+-- @since 4.1.0.0
 instance Eq (MVar a) where
-        (MVar mvar1#) == (MVar mvar2#) = isTrue# (sameMVar# mvar1# mvar2#)
+    (MVar mvar1#) == (MVar mvar2#) = isTrue# (sameMVar# mvar1# mvar2#)
 
 {-
 M-Vars are rendezvous points for concurrent threads.  They begin
@@ -66,9 +68,9 @@ newEmptyMVar = IO $ \ s# ->
 
 -- |Create an 'MVar' which contains the supplied value.
 newMVar :: a -> IO (MVar a)
-newMVar value =
-    newEmptyMVar        >>= \ mvar ->
-    putMVar mvar value  >>
+newMVar value = do
+    mvar <- newEmptyMVar
+    putMVar mvar value
     return mvar
 
 -- |Return the contents of the 'MVar'.  If the 'MVar' is currently
@@ -95,6 +97,7 @@ takeMVar (MVar mvar#) = IO $ \ s# -> takeMVar# mvar# s#
 --
 -- 'readMVar' is multiple-wakeup, so when multiple readers are
 -- blocked on an 'MVar', all of them are woken up at the same time.
+-- The runtime guarantees that all woken threads complete their 'readMVar' operation.
 --
 -- /Compatibility note:/ Prior to base 4.7, 'readMVar' was a combination
 -- of 'takeMVar' and 'putMVar'.  This mean that in the presence of
@@ -104,12 +107,12 @@ takeMVar (MVar mvar#) = IO $ \ s# -> takeMVar# mvar# s#
 -- can be recovered by implementing 'readMVar as follows:
 --
 -- @
---  readMVar :: MVar a -> IO a
---  readMVar m =
---    mask_ $ do
---      a <- takeMVar m
---      putMVar m a
---      return a
+-- readMVar :: MVar a -> IO a
+-- readMVar m =
+--   mask_ $ do
+--     a <- takeMVar m
+--     putMVar m a
+--     return a
 -- @
 readMVar :: MVar a -> IO a
 readMVar (MVar mvar#) = IO $ \ s# -> readMVar# mvar# s#



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4ba088d19dd35859fe0dc5ba47e994e8e2d46efb

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4ba088d19dd35859fe0dc5ba47e994e8e2d46efb
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20230822/35e2623f/attachment-0001.html>


More information about the ghc-commits mailing list