Changes between Version 46 and Version 47 of LightweightConcurrency


Ignore:
Timestamp:
May 18, 2012 9:57:39 PM (2 years ago)
Author:
kc
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • LightweightConcurrency

    v46 v47  
    198198=== MVars === 
    199199 
     200[http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Concurrent-MVar.html MVars] are one of the basic synchronization mechanisms exposed by GHC's concurrency library. A simple user-level implementation of MVar might look like: 
     201 
     202{{{ 
     203newtype MVar a = MVar (PVar (State a)) 
     204data State a = Full a [(a, PTM ())] | Empty [(PVar a, PTM ())] 
     205}}} 
     206 
     207MVar is either empty with a list of pending takers, or full with a value and a list of pending putters. The PTM () action in the full and empty list represents the logic necessary for waking up the pending putters and takers. The following snippet shows the implementation of `takeMVar`. 
     208 
     209{{{ 
     210takeMVar :: MVar a -> IO a  
     211takeMVar (MVar ref) = do 
     212  hole <- atomically $ newPVar undefined  
     213  atomically $ do 
     214    st <- readPVar ref  
     215    case st of 
     216      Empty ts -> do  
     217        s <- getCurrentSCont  
     218        ssa <- getSSA s  
     219        wakeup <- ssa s  
     220        writePVar ref $ v 
     221          where v = Empty $ ts++[(hole, wakeup)]  
     222        switchToNext <- getYCA s  
     223        switchToNext 
     224      Full x ((x', wakeup):ts) -> do  
     225        writePVar hole x  
     226        writePVar ref $ Full x' ts  
     227        wakeup 
     228      otherwise -> ...  
     229  atomically $ readPVar hole 
     230}}} 
     231 
     232Primitive `takeMVar` first creates a hole, which will contain the result. If the MVar happens to be empty, we fetch the scheduleSContAction for the current thread, and append append it along with the hole to the queue. Then, the control switches to the next runnable thread from the scheduler using the yield control action. All of these actions occur atomically within the same transaction. 
     233 
    200234== Capabilities and Tasks == 
    201235