--
-- In particular, the "bigger" functions in this module ('readMVar',
-- 'swapMVar', 'withMVar', 'modifyMVar_' and 'modifyMVar') are simply
--- compositions a 'takeMVar' followed by a 'putMVar' with exception safety.
+-- the composition of a 'takeMVar' followed by a 'putMVar' with
+-- exception safety.
-- These only have atomicity guarantees if all other threads
-- perform a 'takeMVar' before a 'putMVar' as well; otherwise, they may
-- block.
-- in an 'MVar' to the appropriate normal form, or utilize a strict
-- MVar provided by the strict-concurrency package.
--
+-- * Ordering
+--
+-- 'MVar' operations are always observed to take place in the order
+-- they are written in the program, regardless of the memory model of
+-- the underlying machine. This is in contrast to 'IORef' operations
+-- which may appear out-of-order to another thread in some cases.
+--
-- * Example
--
-- Consider the following concurrent data structure, a skip channel.
-- most recent value, or blocks if there are no new values. Multiple
-- readers are supported with a @dupSkipChan@ operation.
--
--- A skip channel is a pair of 'MVar's: the second 'MVar' is a semaphore
--- for this particular reader: it is full if there is a value in the
--- channel that this reader has not read yet, and empty otherwise.
+-- A skip channel is a pair of 'MVar's. The first 'MVar' contains the
+-- current value, and a list of semaphores that need to be notified
+-- when it changes. The second 'MVar' is a semaphore for this particular
+-- reader: it is full if there is a value in the channel that this
+-- reader has not read yet, and empty otherwise.
--
-- @
-- data SkipChan a = SkipChan (MVar (a, [MVar ()])) (MVar ())