Duncan Coutts pushed to branch wip/dcoutts/io-manager-feature-bitset at Glasgow Haskell Compiler / GHC

Commits:

5 changed files:

Changes:

  • libraries/base/src/System/Timeout.hs
    ... ... @@ -23,6 +23,7 @@ import Prelude
    23 23
     import GHC.Internal.Control.Monad
    
    24 24
     import GHC.Internal.Event           (getSystemTimerManager,
    
    25 25
                                 registerTimeout, unregisterTimeout)
    
    26
    +import GHC.Internal.IO.SubSystem    (iomgrInLib)
    
    26 27
     #endif
    
    27 28
     
    
    28 29
     import Control.Concurrent
    
    ... ... @@ -105,8 +106,8 @@ timeout n f
    105 106
         | n <  0    = fmap Just f
    
    106 107
         | n == 0    = return Nothing
    
    107 108
     #if !defined(mingw32_HOST_OS) && !defined(javascript_HOST_ARCH)
    
    108
    -    | rtsSupportsBoundThreads = do
    
    109
    -        -- In the threaded RTS, we use the Timer Manager to delay the
    
    109
    +    | iomgrInLib = do
    
    110
    +        -- If the Timer Manager is available then use it to delay the
    
    110 111
             -- (fairly expensive) 'forkIO' call until the timeout has expired.
    
    111 112
             --
    
    112 113
             -- An additional thread is required for the actual delivery of
    

  • libraries/ghc-internal/src/GHC/Internal/Conc/IO.hs
    ... ... @@ -72,9 +72,12 @@ import GHC.Internal.Prim (Int#, State#, RealWorld,
    72 72
     import GHC.Internal.Real ( fromIntegral )
    
    73 73
     import GHC.Internal.System.Posix.Types
    
    74 74
     
    
    75
    +#if !defined(javascript_HOST_ARCH)
    
    76
    +import GHC.Internal.IO.SubSystem
    
    77
    +#endif
    
    78
    +
    
    75 79
     #if defined(mingw32_HOST_OS)
    
    76 80
     import qualified GHC.Internal.Conc.Windows as Windows
    
    77
    -import GHC.Internal.IO.SubSystem
    
    78 81
     import GHC.Internal.Conc.Windows (asyncRead, asyncWrite, asyncDoProc, asyncReadBA,
    
    79 82
                              asyncWriteBA, ConsoleEvent(..), win32ConsoleHandler,
    
    80 83
                              toWin32ConsoleEvent)
    
    ... ... @@ -102,18 +105,18 @@ ensureIOManagerIsRunning = Windows.ensureIOManagerIsRunning
    102 105
     --
    
    103 106
     -- @since base-4.15
    
    104 107
     interruptIOManager :: IO ()
    
    105
    -#if !defined(mingw32_HOST_OS)
    
    106
    -interruptIOManager = return ()
    
    107
    -#else
    
    108
    -interruptIOManager = Windows.interruptIOManager
    
    108
    +interruptIOManager
    
    109
    +#if defined(mingw32_HOST_OS)
    
    110
    +  | iomgrInLib = Windows.interruptIOManager
    
    109 111
     #endif
    
    112
    +  | otherwise  = return ()
    
    110 113
     
    
    111 114
     ioManagerCapabilitiesChanged :: IO ()
    
    115
    +ioManagerCapabilitiesChanged
    
    112 116
     #if !defined(mingw32_HOST_OS) && !defined(javascript_HOST_ARCH)
    
    113
    -ioManagerCapabilitiesChanged = Event.ioManagerCapabilitiesChanged
    
    114
    -#else
    
    115
    -ioManagerCapabilitiesChanged = return ()
    
    117
    +  | iomgrInLib = Event.ioManagerCapabilitiesChanged
    
    116 118
     #endif
    
    119
    +  | otherwise  = return ()
    
    117 120
     
    
    118 121
     -- | Block the current thread until data is available to read on the
    
    119 122
     -- given file descriptor (GHC only).
    
    ... ... @@ -124,9 +127,9 @@ ioManagerCapabilitiesChanged = return ()
    124 127
     threadWaitRead :: Fd -> IO ()
    
    125 128
     threadWaitRead fd
    
    126 129
     #if !defined(mingw32_HOST_OS) && !defined(javascript_HOST_ARCH)
    
    127
    -  | threaded  = Event.threadWaitRead fd
    
    130
    +  | iomgrInLib = Event.threadWaitRead fd
    
    128 131
     #endif
    
    129
    -  | otherwise = IO $ \s ->
    
    132
    +  | otherwise  = IO $ \s ->
    
    130 133
             case fromIntegral fd of { I# fd# ->
    
    131 134
             case waitRead# fd# s of { s' -> (# s', () #)
    
    132 135
             }}
    
    ... ... @@ -140,9 +143,9 @@ threadWaitRead fd
    140 143
     threadWaitWrite :: Fd -> IO ()
    
    141 144
     threadWaitWrite fd
    
    142 145
     #if !defined(mingw32_HOST_OS) && !defined(javascript_HOST_ARCH)
    
    143
    -  | threaded  = Event.threadWaitWrite fd
    
    146
    +  | iomgrInLib = Event.threadWaitWrite fd
    
    144 147
     #endif
    
    145
    -  | otherwise = IO $ \s ->
    
    148
    +  | otherwise  = IO $ \s ->
    
    146 149
             case fromIntegral fd of { I# fd# ->
    
    147 150
             case waitWrite# fd# s of { s' -> (# s', () #)
    
    148 151
             }}
    
    ... ... @@ -154,9 +157,9 @@ threadWaitWrite fd
    154 157
     threadWaitReadSTM :: Fd -> IO (STM.STM (), IO ())
    
    155 158
     threadWaitReadSTM fd
    
    156 159
     #if !defined(mingw32_HOST_OS) && !defined(javascript_HOST_ARCH)
    
    157
    -  | threaded  = Event.threadWaitReadSTM fd
    
    160
    +  | iomgrInLib = Event.threadWaitReadSTM fd
    
    158 161
     #endif
    
    159
    -  | otherwise = do
    
    162
    +  | otherwise  = do
    
    160 163
           m <- STM.newTVarIO False
    
    161 164
           t <- Sync.forkIO $ do
    
    162 165
             threadWaitRead fd
    
    ... ... @@ -173,9 +176,9 @@ threadWaitReadSTM fd
    173 176
     threadWaitWriteSTM :: Fd -> IO (STM.STM (), IO ())
    
    174 177
     threadWaitWriteSTM fd
    
    175 178
     #if !defined(mingw32_HOST_OS) && !defined(javascript_HOST_ARCH)
    
    176
    -  | threaded  = Event.threadWaitWriteSTM fd
    
    179
    +  | iomgrInLib = Event.threadWaitWriteSTM fd
    
    177 180
     #endif
    
    178
    -  | otherwise = do
    
    181
    +  | otherwise  = do
    
    179 182
           m <- STM.newTVarIO False
    
    180 183
           t <- Sync.forkIO $ do
    
    181 184
             threadWaitWrite fd
    
    ... ... @@ -206,9 +209,9 @@ closeFdWith :: (Fd -> IO ()) -- ^ Low-level action that performs the real close.
    206 209
                 -> IO ()
    
    207 210
     closeFdWith close fd
    
    208 211
     #if !defined(mingw32_HOST_OS) && !defined(javascript_HOST_ARCH)
    
    209
    -  | threaded  = Event.closeFdWith close fd
    
    212
    +  | iomgrInLib = Event.closeFdWith close fd
    
    210 213
     #endif
    
    211
    -  | otherwise = close fd
    
    214
    +  | otherwise  = close fd
    
    212 215
     
    
    213 216
     -- | Suspends the current thread for a given number of microseconds
    
    214 217
     -- (GHC only).
    
    ... ... @@ -223,12 +226,11 @@ closeFdWith close fd
    223 226
     threadDelay :: Int -> IO ()
    
    224 227
     threadDelay time
    
    225 228
     #if defined(mingw32_HOST_OS)
    
    226
    -  | isWindowsNativeIO = Windows.threadDelay time
    
    227
    -  | threaded          = Windows.threadDelay time
    
    229
    +  | iomgrInLib        = Windows.threadDelay time
    
    228 230
     #elif defined(wasm32_HOST_ARCH)
    
    229 231
       | Wasm.isJSFFIUsed  = Wasm.threadDelay time
    
    230 232
     #elif !defined(javascript_HOST_ARCH)
    
    231
    -  | threaded  = Event.threadDelay time
    
    233
    +  | iomgrInLib        = Event.threadDelay time
    
    232 234
     #endif
    
    233 235
       | otherwise         = IO $ \s ->
    
    234 236
             case time of { I# time# ->
    
    ... ... @@ -245,17 +247,12 @@ threadDelay time
    245 247
     registerDelay :: Int -> IO (TVar Bool)
    
    246 248
     registerDelay _usecs
    
    247 249
     #if defined(mingw32_HOST_OS)
    
    248
    -  | isWindowsNativeIO = Windows.registerDelay _usecs
    
    249
    -  | threaded          = Windows.registerDelay _usecs
    
    250
    +  | iomgrInLib        = Windows.registerDelay _usecs
    
    250 251
     #elif !defined(javascript_HOST_ARCH)
    
    251
    -  | threaded          = Event.registerDelay _usecs
    
    252
    +  | iomgrInLib        = Event.registerDelay _usecs
    
    252 253
     #endif
    
    253 254
       | otherwise         = errorWithoutStackTrace "registerDelay: requires -threaded"
    
    254 255
     
    
    255
    -#if !defined(javascript_HOST_ARCH)
    
    256
    -foreign import ccall unsafe "rtsSupportsBoundThreads" threaded :: Bool
    
    257
    -#endif
    
    258
    -
    
    259 256
     
    
    260 257
     -- ---------------------------------------------------------------------------
    
    261 258
     -- PrimIOException
    

  • libraries/ghc-internal/src/GHC/Internal/Conc/POSIX.hs
    ... ... @@ -55,6 +55,7 @@ import GHC.Internal.Data.Maybe (Maybe(..))
    55 55
     import GHC.Internal.Err (errorWithoutStackTrace)
    
    56 56
     import GHC.Internal.Event.Windows.ConsoleEvent
    
    57 57
     import GHC.Internal.IO (unsafePerformIO)
    
    58
    +import GHC.Internal.IO.SubSystem (iomgrInLib)
    
    58 59
     import GHC.Internal.IORef
    
    59 60
     import GHC.Internal.MVar
    
    60 61
     import GHC.Internal.Num (Num(..))
    
    ... ... @@ -120,7 +121,7 @@ asyncWriteBA fd isSock len off bufB =
    120 121
     --
    
    121 122
     threadDelay :: Int -> IO ()
    
    122 123
     threadDelay time
    
    123
    -  | threaded  = waitForDelayEvent time
    
    124
    +  | iomgrInLib = waitForDelayEvent time
    
    124 125
       | otherwise = IO $ \s ->
    
    125 126
             case time of { I# time# ->
    
    126 127
             case delay# time# s of { s' -> (# s', () #)
    
    ... ... @@ -134,11 +135,9 @@ threadDelay time
    134 135
     --
    
    135 136
     registerDelay :: Int -> IO (TVar Bool)
    
    136 137
     registerDelay usecs
    
    137
    -  | threaded = waitForDelayEventSTM usecs
    
    138
    +  | iomgrInLib = waitForDelayEventSTM usecs
    
    138 139
       | otherwise = errorWithoutStackTrace "registerDelay: requires -threaded"
    
    139 140
     
    
    140
    -foreign import ccall unsafe "rtsSupportsBoundThreads" threaded :: Bool
    
    141
    -
    
    142 141
     waitForDelayEvent :: Int -> IO ()
    
    143 142
     waitForDelayEvent usecs = do
    
    144 143
       m <- newEmptyMVar
    
    ... ... @@ -185,7 +184,7 @@ foreign import ccall unsafe "getOrSetGHCConcWindowsIOManagerThreadStore"
    185 184
     
    
    186 185
     ensureIOManagerIsRunning :: IO ()
    
    187 186
     ensureIOManagerIsRunning
    
    188
    -  | threaded  = startIOManagerThread
    
    187
    +  | iomgrInLib = startIOManagerThread
    
    189 188
       | otherwise = return ()
    
    190 189
     
    
    191 190
     interruptIOManager :: IO ()
    

  • libraries/ghc-internal/src/GHC/Internal/Event/Thread.hs
    ... ... @@ -49,6 +49,7 @@ import GHC.Internal.IO (mask_, uninterruptibleMask_, onException)
    49 49
     import GHC.Internal.IO.Exception (ioError)
    
    50 50
     import GHC.Internal.IOArray (IOArray, newIOArray, readIOArray, writeIOArray,
    
    51 51
                         boundsIOArray)
    
    52
    +import GHC.Internal.IO.SubSystem (iomgrInRTS)
    
    52 53
     import GHC.Internal.MVar (MVar, newEmptyMVar, newMVar, putMVar, takeMVar)
    
    53 54
     import GHC.Internal.Event.Control (controlWriteFd)
    
    54 55
     import GHC.Internal.Event.Internal (eventIs, evtClose)
    
    ... ... @@ -325,7 +326,7 @@ timerManagerThreadVar = unsafePerformIO $ do
    325 326
     
    
    326 327
     ensureIOManagerIsRunning :: IO ()
    
    327 328
     ensureIOManagerIsRunning
    
    328
    -  | not threaded = return ()
    
    329
    +  | iomgrInRTS = return ()
    
    329 330
       | otherwise = do
    
    330 331
           startIOManagerThreads
    
    331 332
           startTimerManagerThread
    
    ... ... @@ -409,8 +410,6 @@ startTimerManagerThread = modifyMVar_ timerManagerThreadVar $ \old -> do
    409 410
               create
    
    410 411
             _other         -> return st
    
    411 412
     
    
    412
    -foreign import ccall unsafe "rtsSupportsBoundThreads" threaded :: Bool
    
    413
    -
    
    414 413
     ioManagerCapabilitiesChanged :: IO ()
    
    415 414
     ioManagerCapabilitiesChanged =
    
    416 415
       withMVar ioManagerLock $ \_ -> do
    

  • libraries/ghc-internal/src/GHC/Internal/IO/SubSystem.hs
    ... ... @@ -51,6 +51,7 @@ module GHC.Internal.IO.SubSystem (
    51 51
       -- other. This can instead now be done conditionally on the I\/O manager
    
    52 52
       -- feature 'iomgrInRTS'.
    
    53 53
       iomgrInRTS,
    
    54
    +  iomgrInLib,
    
    54 55
       iomgrUsesHANDLEs,
    
    55 56
      ) where
    
    56 57
     
    
    ... ... @@ -150,6 +151,11 @@ ioManagerFeatureBitmask IOMgrUsesHANDLEs = 1## `uncheckedShiftL#` 1#
    150 151
     iomgrInRTS :: Bool
    
    151 152
     iomgrInRTS = ioManagerFeature IOMgrInRTS
    
    152 153
     
    
    154
    +-- | The inverse of 'iomgrInRTS'. In some cases the logic may read more clearly
    
    155
    +-- this way round.
    
    156
    +iomgrInLib :: Bool
    
    157
    +iomgrInLib = not iomgrInRTS
    
    158
    +
    
    153 159
     -- | This means that the I\/O manager uses the Win32 API's HANDLE type to
    
    154 160
     -- refer to open files. The inverse is that it uses Posix style fds.
    
    155 161
     -- This is always false on Poisx platforms, while on Windows it is true