2 % (c) The GRASP/AQUA Project, Glasgow University, 1995
4 \section[SampleVar]{Sample variables}
6 Sample variables are slightly different from a normal @MVar@:
9 \item Reading an empty @SampleVar@ causes the reader to block.
10 (same as @takeMVar@ on empty @MVar@)
11 \item Reading a filled @SampleVar@ empties it and returns value.
13 \item Writing to an empty @SampleVar@ fills it with a value, and
14 potentially, wakes up a blocked reader (same as for @putMVar@ on empty @MVar@).
15 \item Writing to a filled @SampleVar@ overwrites the current value.
16 (different from @putMVar@ on full @MVar@.)
22 SampleVar(..), --:: type _ =
24 newSampleVar, --:: IO (SampleVar a)
25 emptySampleVar, --:: SampleVar a -> IO ()
26 readSample, --:: SampleVar a -> IO a
27 writeSample --:: SampleVar a -> a -> IO ()
32 import PreludePrimIO ( newEmptyMVar, newMVar, putMVar,
33 readMVar, swapMVar, takeMVar, _MVar
40 = _MVar (Int, -- 1 == full
42 -- <0 no of readers blocked
47 Initally, a @SampleVar@ is empty/unfilled.
51 newSampleVar :: IO (SampleVar a)
53 = newEmptyMVar >>= \ val ->
56 emptySampleVar :: SampleVar a -> IO ()
58 = takeMVar v >>= \ (readers,var) ->
62 putMVar v (readers,var)
71 -- filled => make empty and grab sample
72 -- not filled => try to grab value, empty when read val.
74 readSample :: SampleVar a -> IO a
76 = takeMVar svar >>= \ (readers,val) ->
77 putMVar svar (readers-1,val) >>
81 -- filled => overwrite
82 -- not filled => fill, write val
84 writeSample :: SampleVar a -> a -> IO ()
86 = takeMVar svar >>= \ (readers, val) ->
93 putMVar svar (min 1 (readers+1), val)