Changes between Version 1 and Version 2 of IOManager

May 28, 2009 4:18:09 PM (7 years ago)



  • IOManager

    v1 v2  
    11= The I/O Manager =
    3 ''This page is under construction.''
     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.