[commit: base] : Introduce IORef to refer to array of IO managers. (1e30209)

Johan Tibell johan.tibell at gmail.com
Tue Feb 12 07:51:02 CET 2013


Repository : ssh://darcs.haskell.org//srv/darcs/packages/base

On branch  : 

http://hackage.haskell.org/trac/ghc/changeset/1e30209053f7ad3c7f4b939b2458701fa51bc8f0

>---------------------------------------------------------------

commit 1e30209053f7ad3c7f4b939b2458701fa51bc8f0
Author: Andreas Voellmy <andreas.voellmy at gmail.com>
Date:   Sat Dec 22 20:11:21 2012 -0500

    Introduce IORef to refer to array of IO managers.
    
    This change prepares the way for supporting changing number of IO managers when number of capabilities changes.

>---------------------------------------------------------------

 GHC/Event/Thread.hs |   45 +++++++++++++++++++++++++--------------------
 1 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/GHC/Event/Thread.hs b/GHC/Event/Thread.hs
index 8c5989b..bef907c 100644
--- a/GHC/Event/Thread.hs
+++ b/GHC/Event/Thread.hs
@@ -24,12 +24,13 @@ import Foreign.C.Error (eBADF, errnoToIOError)
 import Foreign.Ptr (Ptr)
 import GHC.Base
 import GHC.Conc.Sync (TVar, ThreadId, ThreadStatus(..), atomically, forkIO,
-                      labelThread, modifyMVar_, newTVar, sharedCAF,
+                      labelThread, modifyMVar_, withMVar, newTVar, sharedCAF,
                       numCapabilities, threadCapability, myThreadId, forkOn,
                       threadStatus, writeTVar, newTVarIO, readTVar, retry,throwSTM,STM)
 import GHC.IO (mask_, onException)
 import GHC.IO.Exception (ioError)
-import GHC.IOArray (IOArray, newIOArray, readIOArray, writeIOArray)
+import GHC.IOArray (IOArray, newIOArray, readIOArray, writeIOArray,
+                    boundsIOArray)
 import GHC.MVar (MVar, newEmptyMVar, newMVar, putMVar, takeMVar)
 import GHC.Event.Internal (eventIs, evtClose)
 import GHC.Event.Manager (Event, EventManager, evtRead, evtWrite, loop,
@@ -93,7 +94,11 @@ closeFdWith :: (Fd -> IO ())        -- ^ Action that performs the close.
             -> Fd                   -- ^ File descriptor to close.
             -> IO ()
 closeFdWith close fd = do
-  tableVars <- forM [0,1..numCapabilities-1] (getCallbackTableVar fd)
+  eventManagerArray <- readIORef eventManager
+  let (low, high) = boundsIOArray eventManagerArray
+  tableVars <- forM [low..high] $ \i -> do
+    Just (_,!mgr) <- readIOArray eventManagerArray i
+    return (mgr, M.callbackTableVar mgr fd)
   mask_ $ do
     tables <- forM tableVars (takeMVar.snd)
     close fd
@@ -102,13 +107,6 @@ closeFdWith close fd = do
       tableVars
       tables
 
-getCallbackTableVar :: Fd
-                       -> Int
-                       -> IO (EventManager, MVar (IM.IntMap [M.FdData]))
-getCallbackTableVar fd cap =
-  do Just (_,!mgr) <- readIOArray eventManager cap
-     return (mgr, M.callbackTableVar mgr fd)
-
 threadWait :: Event -> Fd -> IO ()
 threadWait evt fd = mask_ $ do
   m <- newEmptyMVar
@@ -168,15 +166,17 @@ getSystemEventManager :: IO EventManager
 getSystemEventManager = do
   t <- myThreadId
   (cap, _) <- threadCapability t
-  Just (_,mgr) <- readIOArray eventManager cap
+  eventManagerArray <- readIORef eventManager
+  Just (_,mgr) <- readIOArray eventManagerArray cap
   return mgr
 
 foreign import ccall unsafe "getOrSetSystemEventThreadEventManagerStore"
     getOrSetSystemEventThreadEventManagerStore :: Ptr a -> IO (Ptr a)
 
-eventManager :: IOArray Int (Maybe (ThreadId, EventManager))
+eventManager :: IORef (IOArray Int (Maybe (ThreadId, EventManager)))
 eventManager = unsafePerformIO $ do
-    em <- newIOArray (0, numCapabilities - 1) Nothing
+    eventManagerArray <- newIOArray (0, numCapabilities - 1) Nothing
+    em <- newIORef eventManagerArray
     sharedCAF em getOrSetSystemEventThreadEventManagerStore
 {-# NOINLINE eventManager #-}
 
@@ -220,18 +220,21 @@ ensureIOManagerIsRunning
       startTimerManagerThread
 
 startIOManagerThreads :: IO ()
-startIOManagerThreads =
-  modifyMVar_ ioManagerLock $ \_ ->
-  forM_ [0,1..numCapabilities-1] startIOManagerThread
+startIOManagerThreads = do
+  eventManagerArray <- readIORef eventManager
+  let (low, high) = boundsIOArray eventManagerArray
+  withMVar ioManagerLock $ \_ ->
+    forM_ [low..high] startIOManagerThread
   
 startIOManagerThread :: Int -> IO ()
 startIOManagerThread i = do
+  eventManagerArray <- readIORef eventManager
   let create = do
         !mgr <- new True
         !t <- forkOn i $ loop mgr
         labelThread t "IOManager"
-        writeIOArray eventManager i (Just (t,mgr))
-  old <- readIOArray eventManager i
+        writeIOArray eventManagerArray i (Just (t,mgr))
+  old <- readIOArray eventManagerArray i
   case old of
     Nothing            -> create
     Just (t,em) -> do
@@ -277,8 +280,10 @@ startTimerManagerThread = modifyMVar_ timerManagerThreadVar $ \old -> do
 
 shutdownManagers :: IO ()
 shutdownManagers =
-  do forM_ [0,1..numCapabilities-1] $ \i -> do
-       mmgr <- readIOArray eventManager i
+  do eventManagerArray <- readIORef eventManager
+     let (low, high) = boundsIOArray eventManagerArray
+     forM_ [low..high] $ \i -> do
+       mmgr <- readIOArray eventManagerArray i
        case mmgr of
          Nothing -> return ()
          Just (_,mgr) -> M.shutdown mgr





More information about the ghc-commits mailing list