Changes between Initial Version and Version 1 of Commentary/Rts/IOManager

Oct 17, 2011 10:06:45 PM (4 years ago)



  • Commentary/Rts/IOManager

    v1 v1  
     1= The I/O Manager = 
     3This page describes the internals of the I/O manager, the latest version of which can be found in [ 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. 
     5The RTS keeps a global list of pending events, unsuprising called `pendingEvents`, containing a elements of the following data type: 
     8data IOReq 
     9  = Read   {-# UNPACK #-} !Fd {-# UNPACK #-} !(MVar ()) 
     10  | Write  {-# UNPACK #-} !Fd {-# UNPACK #-} !(MVar ()) 
     13When a thread wants to read from a file descriptor `fd` it calls `threadWaitRead` which in turn calls `waitForReadEvent`. 
     16waitForReadEvent :: Fd -> IO () 
     17waitForReadEvent fd = do 
     18  m <- newEmptyMVar 
     19  atomicModifyIORef pendingEvents (\xs -> (Read fd m : xs, ())) 
     20  prodServiceThread 
     21  takeMVar m 
     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: 
     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.