Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
GHC
GHC
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 4,246
    • Issues 4,246
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
    • Iterations
  • Merge Requests 397
    • Merge Requests 397
  • Requirements
    • Requirements
    • List
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
  • Security & Compliance
    • Security & Compliance
    • Dependency List
    • License Compliance
  • Operations
    • Operations
    • Incidents
    • Environments
  • Analytics
    • Analytics
    • CI / CD
    • Code Review
    • Insights
    • Issue
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Collapse sidebar
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
  • Glasgow Haskell Compiler
  • GHCGHC
  • Wiki
    • Commentary
    • Rts
  • io manager

Last edited by Takenobu Tani Jun 22, 2020
Page history New page

io manager

The I/O Manager

This page describes the internals of the I/O manager, the latest version of which can be found in GHC.Event. 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.

ezyang: WARNING: some of this information may be out of date

The RTS keeps a global list of pending events, unsuprising called pendingEvents, containing a elements of the following data type:

data IOReq
  = Read   {-# UNPACK #-} !Fd {-# UNPACK #-} !(MVar ())
  | Write  {-# UNPACK #-} !Fd {-# UNPACK #-} !(MVar ())

When a thread wants to read from a file descriptor fd it calls threadWaitRead which in turn calls waitForReadEvent.

waitForReadEvent :: Fd -> IO ()
waitForReadEvent fd = do
  m <- newEmptyMVar
  atomicModifyIORef pendingEvents (\xs -> (Read fd m : xs, ()))
  prodServiceThread
  takeMVar m

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:

  1. Pick up new I/O requests from pendingRequests and set the variable to the empty list.
  2. Create data structures appropriate for calling select.
  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.
  4. Repeat from step 1.
Clone repository

GHC Home
GHC User's Guide

Joining In

Newcomers info
Mailing Lists & IRC
The GHC Team

Documentation

GHC Status Info
Working conventions
Building Guide
Debugging
Commentary

Wiki

Title Index
Recent Changes