Changes between Version 2 and Version 3 of IOManager


Ignore:
Timestamp:
Oct 17, 2011 10:06:50 PM (3 years ago)
Author:
dterei
Comment:

moved page

Legend:

Unmodified
Added
Removed
Modified
  • IOManager

    v2 v3  
    1 = The I/O Manager = 
    2  
    3 This page describes the internals of the I/O manager, the latest version of which can be found in [http://darcs.haskell.org/libraries/base/GHC/Conc.lhs GHC.Conc], in the "Thread IO API" section. The I/O manager's job is to to provide a blocking I/O API to the user without forcing the RTS to create one operating system thread per Haskell thread. We here focus on the ''threaded'' RTS on non-Windows platforms. 
    4  
    5 The RTS keeps a global list of pending events, unsuprising called `pendingEvents`, containing a elements of the following data type: 
    6  
    7 {{{ 
    8 data IOReq 
    9   = Read   {-# UNPACK #-} !Fd {-# UNPACK #-} !(MVar ()) 
    10   | Write  {-# UNPACK #-} !Fd {-# UNPACK #-} !(MVar ()) 
    11 }}} 
    12  
    13 When a thread wants to read from a file descriptor `fd` it calls `threadWaitRead` which in turn calls `waitForReadEvent`. 
    14  
    15 {{{ 
    16 waitForReadEvent :: Fd -> IO () 
    17 waitForReadEvent fd = do 
    18   m <- newEmptyMVar 
    19   atomicModifyIORef pendingEvents (\xs -> (Read fd m : xs, ())) 
    20   prodServiceThread 
    21   takeMVar m 
    22 }}} 
    23  
    24 `waitForReadEvent` creates a new `MVar`, adds it to `pendingEvents` and finally blocks on it. `pendingEvents` gets read by the I/O manager thread which runs the event loop, in GHC called `service_loop`. It roughly performs these steps: 
    25  
    26  1. Pick up new I/O requests from `pendingRequests` and set the variable to the empty list. 
    27  2. Create data structures appropriate for calling `select`. 
    28  3. For each `Read` request in `pendingEvents` check if the file descriptor is in the ready set returned by `select`. If so perform a `putMVar` on the `MVar` associated with that request to wake up the blocked thread. 
    29  4. Repeat from step 1.