[Git][ghc/ghc][master] Update and expand atomic modification Haddocks

Marge Bot (@marge-bot) gitlab at gitlab.haskell.org
Sun Mar 26 19:33:17 UTC 2023



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


Commits:
4f93de88 by David Feuer at 2023-03-26T15:33:02-04:00
Update and expand atomic modification Haddocks

* The documentation for `atomicModifyIORef` and `atomicModifyIORef'`
  were incomplete, and the documentation for `atomicModifyIORef` was
  out of date. Update and expand.

* Remove a useless lazy pattern match in the definition of
  `atomicModifyIORef`. The pair it claims to match lazily
  was already forced by `atomicModifyIORef2`.

- - - - -


2 changed files:

- libraries/base/Data/IORef.hs
- libraries/base/GHC/IORef.hs


Changes:

=====================================
libraries/base/Data/IORef.hs
=====================================
@@ -85,21 +85,45 @@ modifyIORef' ref f = do
 -- is recommended that if you need to do anything more complicated
 -- then using 'Control.Concurrent.MVar.MVar' instead is a good idea.
 --
--- 'atomicModifyIORef' does not apply the function strictly.  This is important
--- to know even if all you are doing is replacing the value.  For example, this
--- will leak memory:
+-- Conceptually,
 --
--- >ref <- newIORef '1'
--- >forever $ atomicModifyIORef ref (\_ -> ('2', ()))
+-- @
+-- atomicModifyIORef ref f = do
+--   -- Begin atomic block
+--   old <- 'readIORef' ref
+--   let r = f old
+--       new = fst r
+--   'writeIORef' ref new
+--   -- End atomic block
+--   case r of
+--     (_new, res) -> pure res
+-- @
 --
--- Use 'atomicModifyIORef'' or 'atomicWriteIORef' to avoid this problem.
+-- The actions in the section labeled \"atomic block\" are not subject to
+-- interference from other threads. In particular, it is impossible for the
+-- value in the 'IORef' to change between the 'readIORef' and 'writeIORef'
+-- invocations.
 --
--- This function imposes a memory barrier, preventing reordering;
--- see "Data.IORef#memmodel" for details.
+-- The user-supplied function is applied to the value stored in the 'IORef',
+-- yielding a new value to store in the 'IORef' and a value to return. After
+-- the new value is (lazily) stored in the 'IORef', @atomicModifyIORef@ forces
+-- the result pair, but does not force either component of the result. To force
+-- /both/ components, use 'atomicModifyIORef''.
+--
+-- Note that
+--
+-- @atomicModifyIORef ref (\_ -> undefined)@
+--
+-- will raise an exception in the calling thread, but will /also/
+-- install the bottoming value in the 'IORef', where it may be read by
+-- other threads.
+--
+-- This function imposes a memory barrier, preventing reordering around the
+-- \"atomic block\"; see "Data.IORef#memmodel" for details.
 --
 atomicModifyIORef :: IORef a -> (a -> (a,b)) -> IO b
 atomicModifyIORef ref f = do
-  (_old, ~(_new, res)) <- atomicModifyIORef2 ref f
+  (_old, (_new, res)) <- atomicModifyIORef2 ref f
   pure res
 
 -- | Variant of 'writeIORef'. The prefix "atomic" relates to a fact that


=====================================
libraries/base/GHC/IORef.hs
=====================================
@@ -134,9 +134,28 @@ atomicSwapIORef (IORef (STRef ref)) new = IO $ \s ->
 
 data Box a = Box a
 
--- | Strict version of 'Data.IORef.atomicModifyIORef'. This forces both
--- the value stored in the 'IORef' and the value returned. The new value
--- is installed in the 'IORef' before the returned value is forced.
+-- | A strict version of 'Data.IORef.atomicModifyIORef'.  This forces both the
+-- value stored in the 'IORef' and the value returned.
+--
+-- Conceptually,
+--
+-- @
+-- atomicModifyIORef' ref f = do
+--   -- Begin atomic block
+--   old <- 'readIORef' ref
+--   let r = f old
+--       new = fst r
+--   'writeIORef' ref new
+--   -- End atomic block
+--   case r of
+--     (!_new, !res) -> pure res
+-- @
+--
+-- The actions in the \"atomic block\" are not subject to interference
+-- by other threads. In particular, the value in the 'IORef' cannot
+-- change between the 'readIORef' and 'writeIORef' invocations.
+--
+-- The new value is installed in the 'IORef' before either value is forced.
 -- So
 --
 -- @atomicModifyIORef' ref (\x -> (x+1, undefined))@
@@ -144,8 +163,18 @@ data Box a = Box a
 -- will increment the 'IORef' and then throw an exception in the calling
 -- thread.
 --
--- This function imposes a memory barrier, preventing reordering;
--- see "Data.IORef#memmodel" for details.
+-- @atomicModifyIORef' ref (\x -> (undefined, x))@
+--
+-- and
+--
+-- @atomicModifyIORef' ref (\_ -> undefined)@
+--
+-- will each raise an exception in the calling thread, but will /also/
+-- install the bottoming value in the 'IORef', where it may be read by
+-- other threads.
+--
+-- This function imposes a memory barrier, preventing reordering around
+-- the \"atomic block\"; see "Data.IORef#memmodel" for details.
 --
 -- @since 4.6.0.0
 atomicModifyIORef' :: IORef a -> (a -> (a,b)) -> IO b



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

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4f93de888fb8be5241b476442045eb40b2a5abbd
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/20230326/9cbf1c35/attachment-0001.html>


More information about the ghc-commits mailing list