diff --git a/docs/users_guide/runtime_control.rst b/docs/users_guide/runtime_control.rst index 8ab6b2c8ea1a35d7d54eb4df97c6c2808bcbdf8b..370593d207e1658478479507ebc1c69c2b780c57 100644 --- a/docs/users_guide/runtime_control.rst +++ b/docs/users_guide/runtime_control.rst @@ -308,6 +308,23 @@ Miscellaneous RTS options undue memory usage shown in reporting tools, so with this flag it can be turned off. +.. rts-flag:: --io-manager=(name) + + Select the I/O manager to use. On some combinations of platform and + threaded/non-threaded RTS way there is a choice of more than one + implementation of I/O manager. This flag lets you override the default + and select one by name. + + Currently the available I/O managers are: + + ================ ========= ============ + Name Platforms RTS way + ================ ========= ============ + ``select`` Posix Non-threaded + ``mio`` All Threaded + ``win32-legacy`` Windows Non-threaded + ``winio`` Windows All + ================ ========= ============ .. rts-flag:: -xp diff --git a/libraries/base/src/GHC/RTS/Flags.hs b/libraries/base/src/GHC/RTS/Flags.hs index e9e2f00f185cd7ed912ba348ebc04395dd3b966e..24dd2203de745e0fc8956d440fead02de0d482b6 100644 --- a/libraries/base/src/GHC/RTS/Flags.hs +++ b/libraries/base/src/GHC/RTS/Flags.hs @@ -25,6 +25,7 @@ module GHC.RTS.Flags , GCFlags (..) , ConcFlags (..) , MiscFlags (..) + , IoManagerFlag (..) , DebugFlags (..) , DoCostCentres (..) , CCFlags (..) @@ -35,12 +36,12 @@ module GHC.RTS.Flags , TickyFlags (..) , ParFlags (..) , HpcFlags (..) - , IoSubSystem (..) + , {-# DEPRECATED "import GHC.IO.SubSystem (IoSubSystem (..))" #-} + IoSubSystem (..) , getRTSFlags , getGCFlags , getConcFlags , getMiscFlags - , getIoManagerFlag , getDebugFlags , getCCFlags , getProfFlags @@ -51,3 +52,4 @@ module GHC.RTS.Flags ) where import GHC.Internal.RTS.Flags +import GHC.Internal.IO.SubSystem (IoSubSystem(..)) diff --git a/libraries/ghc-internal/src/GHC/Internal/IO/SubSystem.hs b/libraries/ghc-internal/src/GHC/Internal/IO/SubSystem.hs index e62e3e947332e0ffeaa521f9bdcd485637c09ecc..747e5a48b48c4f4d5fa801fc8bb3e32fdc9809ed 100644 --- a/libraries/ghc-internal/src/GHC/Internal/IO/SubSystem.hs +++ b/libraries/ghc-internal/src/GHC/Internal/IO/SubSystem.hs @@ -34,14 +34,27 @@ module GHC.Internal.IO.SubSystem ( ) where import GHC.Internal.Base -import GHC.Internal.RTS.Flags #if defined(mingw32_HOST_OS) import GHC.Internal.IO.Unsafe +import GHC.Internal.Foreign.Ptr +import GHC.Internal.Foreign.Storable +import GHC.Internal.Foreign.C.Types +import GHC.Internal.Foreign.Marshal.Utils #endif infixl 7 <!> +-- | The I/O SubSystem to use in the program. +-- +-- @since base-4.9.0.0 +data IoSubSystem + = IoPOSIX -- ^ Use a POSIX I/O Sub-System + | IoNative -- ^ Use platform native Sub-System. For unix OSes this is the + -- same as IoPOSIX, but on Windows this means use the Windows + -- native APIs for I/O, including IOCP and RIO. + deriving (Eq) + -- | Conditionally execute an action depending on the configured I/O subsystem. -- On POSIX systems always execute the first action. -- On Windows execute the second action if WINIO as active, otherwise fall back to @@ -64,10 +77,37 @@ conditional posix _ = posix isWindowsNativeIO :: Bool isWindowsNativeIO = False <!> True +-- | The 'IoSubSystem' in use. +-- +-- This is needed to optimize support for different IO Managers on Windows. +-- GHC supports both the new WinIO manager as well as the old MIO (threaded), +-- and ancient win32-legacy (non-threaded) ones. The WinIO manager uses native +-- Win32 HANDLEs, whereas the other two use posix style FDs (via translation +-- layers). +-- +-- In many places in the I\/O base library code, for correctness or performance +-- on Windows, we have to take different code paths depending on which style of +-- IO manager is in use. The IO manager is set on RTS startup (and the default +-- choice can be overridden using RTS flags). On Windows this value is obtained +-- by reading a global variable that is set by the RTS IOManager on startup. +-- +-- On non-Windows systems this value is always 'IoPOSIX'. +-- ioSubSystem :: IoSubSystem #if defined(mingw32_HOST_OS) -{-# NOINLINE ioSubSystem #-} -ioSubSystem = unsafeDupablePerformIO getIoManagerFlag +{-# INLINE ioSubSystem #-} +ioSubSystem = + case toBool ioManagerIsWin32NativeCBool of + False -> IoPOSIX + True -> IoNative + +{-# NOINLINE ioManagerIsWin32NativeCBool #-} +ioManagerIsWin32NativeCBool :: CBool +ioManagerIsWin32NativeCBool = + unsafeDupablePerformIO $ peek ioManagerIsWin32NativePtr + +foreign import ccall "&rts_IOManagerIsWin32Native" + ioManagerIsWin32NativePtr :: Ptr CBool #else ioSubSystem = IoPOSIX #endif diff --git a/libraries/ghc-internal/src/GHC/Internal/RTS/Flags.hsc b/libraries/ghc-internal/src/GHC/Internal/RTS/Flags.hsc index 4a3e941762899ec6318fcf4c7a31c441cdd6b32c..c11346659a981f4e5dddd44fdb2819892f200347 100644 --- a/libraries/ghc-internal/src/GHC/Internal/RTS/Flags.hsc +++ b/libraries/ghc-internal/src/GHC/Internal/RTS/Flags.hsc @@ -27,6 +27,7 @@ module GHC.Internal.RTS.Flags , GCFlags (..) , ConcFlags (..) , MiscFlags (..) + , IoManagerFlag (..) , DebugFlags (..) , DoCostCentres (..) , CCFlags (..) @@ -37,12 +38,10 @@ module GHC.Internal.RTS.Flags , TickyFlags (..) , ParFlags (..) , HpcFlags (..) - , IoSubSystem (..) , getRTSFlags , getGCFlags , getConcFlags , getMiscFlags - , getIoManagerFlag , getDebugFlags , getCCFlags , getProfFlags @@ -103,32 +102,6 @@ instance Enum GiveGCStats where toEnum #{const VERBOSE_GC_STATS} = VerboseGCStats toEnum e = errorWithoutStackTrace ("invalid enum for GiveGCStats: " ++ show e) --- | The I/O SubSystem to use in the program. --- --- @since base-4.9.0.0 -data IoSubSystem - = IoPOSIX -- ^ Use a POSIX I/O Sub-System - | IoNative -- ^ Use platform native Sub-System. For unix OSes this is the - -- same as IoPOSIX, but on Windows this means use the Windows - -- native APIs for I/O, including IOCP and RIO. - deriving (Eq, Show) - --- | @since base-4.9.0.0 -instance Enum IoSubSystem where - fromEnum IoPOSIX = #{const IO_MNGR_POSIX} - fromEnum IoNative = #{const IO_MNGR_NATIVE} - - toEnum #{const IO_MNGR_POSIX} = IoPOSIX - toEnum #{const IO_MNGR_NATIVE} = IoNative - toEnum e = errorWithoutStackTrace ("invalid enum for IoSubSystem: " ++ show e) - --- | @since base-4.9.0.0 -instance Storable IoSubSystem where - sizeOf = sizeOf . fromEnum - alignment = sizeOf . fromEnum - peek ptr = fmap toEnum $ peek (castPtr ptr) - poke ptr v = poke (castPtr ptr) (fromEnum v) - -- | Parameters of the garbage collector. -- -- @since base-4.8.0.0 @@ -191,12 +164,20 @@ data MiscFlags = MiscFlags , linkerAlwaysPic :: Bool , linkerMemBase :: Word -- ^ address to ask the OS for memory for the linker, 0 ==> off - , ioManager :: IoSubSystem + , ioManager :: IoManagerFlag , numIoWorkerThreads :: Word32 } deriving ( Show -- ^ @since base-4.8.0.0 , Generic -- ^ @since base-4.15.0.0 ) +data IoManagerFlag = + IoManagerFlagAuto + | IoManagerFlagSelect -- ^ Unix only, non-threaded RTS only + | IoManagerFlagMIO -- ^ cross-platform, threaded RTS only + | IoManagerFlagWinIO -- ^ Windows only + | IoManagerFlagWin32Legacy -- ^ Windows only, non-threaded RTS only + deriving (Eq, Enum, Show) + -- | Flags to control debugging output & extra checking in various -- subsystems. -- @@ -552,36 +533,6 @@ getMiscFlags = do <*> (fromIntegral <$> (#{peek MISC_FLAGS, numIoWorkerThreads} ptr :: IO Word32)) -{- Note [The need for getIoManagerFlag] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - GHC supports both the new WINIO manager - as well as the old MIO one. In order to - decide which code path to take we often - have to inspect what the user selected at - RTS startup. - - We could use getMiscFlags but then we end up with core containing - reads for all MiscFlags. These won't be eliminated at the core level - even if it's obvious we will only look at the ioManager part of the - ADT. - - We could add a INLINE pragma, but that just means whatever we inline - into is likely to be inlined. So rather than adding a dozen pragmas - we expose a lean way to query this particular flag. It's not satisfying - but it works well enough and allows these checks to be inlined nicely. - --} - -{-# INLINE getIoManagerFlag #-} --- | Needed to optimize support for different IO Managers on Windows. --- See Note [The need for getIoManagerFlag] -getIoManagerFlag :: IO IoSubSystem -getIoManagerFlag = do - let ptr = (#ptr RTS_FLAGS, MiscFlags) rtsFlagsPtr - mgrFlag <- (#{peek MISC_FLAGS, ioManager} ptr :: IO Word32) - return $ (toEnum . fromIntegral) mgrFlag - getDebugFlags :: IO DebugFlags getDebugFlags = do let ptr = (#ptr RTS_FLAGS, DebugFlags) rtsFlagsPtr diff --git a/rts/IOManager.c b/rts/IOManager.c index 74d48ed5414e8c1868aacb7b1cbc284206066c72..2592ea4826de5c0cda9850694a31854b1e397e66 100644 --- a/rts/IOManager.c +++ b/rts/IOManager.c @@ -33,6 +33,174 @@ #include "win32/AsyncWinIO.h" #endif +#include <string.h> + + +/* Global var to tell us which I/O manager impl we are using */ +IOManagerType iomgr_type; + +#if defined(mingw32_HOST_OS) +/* Global var (only on Windows) that is exported to be shared with the I/O code + * in the base library to tell us which style of I/O manager we are using: one + * that uses the Windows native API HANDLEs, or one that uses Posix style fds. + */ +bool rts_IOManagerIsWin32Native = false; +#endif + +enum IOManagerAvailability +parseIOManagerFlag(const char *iomgrstr, IO_MANAGER_FLAG *flag) +{ + if (strcmp("select", iomgrstr) == 0) { +#if defined(IOMGR_ENABLED_SELECT) + *flag = IO_MNGR_FLAG_SELECT; + return IOManagerAvailable; +#else + return IOManagerUnavailable; +#endif + } + else if (strcmp("mio", iomgrstr) == 0) { +#if defined(IOMGR_ENABLED_MIO_POSIX) || defined(IOMGR_ENABLED_MIO_WIN32) + *flag = IO_MNGR_FLAG_MIO; + return IOManagerAvailable; +#else + return IOManagerUnavailable; +#endif + *flag = IO_MNGR_FLAG_MIO; + } + else if (strcmp("winio", iomgrstr) == 0) { +#if defined(IOMGR_ENABLED_WINIO) + *flag = IO_MNGR_FLAG_WINIO; + return IOManagerAvailable; +#else + return IOManagerUnavailable; +#endif + } + else if (strcmp("win32-legacy", iomgrstr) == 0) { +#if defined(IOMGR_ENABLED_WIN32_LEGACY) + *flag = IO_MNGR_FLAG_WIN32_LEGACY; + return IOManagerAvailable; +#else + return IOManagerUnavailable; +#endif + } + else if (strcmp("auto", iomgrstr) == 0) { + *flag = IO_MNGR_FLAG_AUTO; + return IOManagerAvailable; + } + /* Two deprecated aliases. These aliases only had any effect on Windows, + * but were available as RTS flags on all platforms. The "native" flag + * refers to the newer Windows WinIO IO manager (threaded or non-threaded), + * while (somewhat confusingly) the "posix" flag refers to the older + * Windows I/O managers (win32-legacy and mio). On non-Windows, we now make + * these flags equivalent to IO_MNGR_FLAG_AUTO. + */ + else if (strcmp("native", iomgrstr) == 0) { +#if defined(mingw32_HOST_OS) + /* On windows "native" is now an alias for IO_MNGR_FLAG_WINIO */ +#if defined(IOMGR_ENABLED_WINIO) + *flag = IO_MNGR_FLAG_WINIO; + return IOManagerAvailable; +#else + return IOManagerUnavailable; +#endif +#else // !defined(mingw32_HOST_OS) + *flag = IO_MNGR_FLAG_AUTO; + return IOManagerAvailable; +#endif + } + else if (strcmp("posix", iomgrstr) == 0) { +#if defined(mingw32_HOST_OS) + /* On Windows "posix" is now an alias for either IO_MNGR_FLAG_MIO or + * IO_MNGR_FLAG_WIN32_LEGACY */ +#if defined(IOMGR_ENABLED_MIO_WIN32) + *flag = IO_MNGR_FLAG_MIO; + return IOManagerAvailable; +#elif defined(IOMGR_ENABLED_WIN32_LEGACY) + *flag = IO_MNGR_FLAG_WIN32_LEGACY; + return IOManagerAvailable; +#else + return IOManagerUnavailable; +#endif +#else // !defined(mingw32_HOST_OS) + *flag = IO_MNGR_FLAG_AUTO; + return IOManagerAvailable; +#endif + } + else { + return IOManagerUnrecognised; + } +} + +/* Based on the I/O manager RTS flag, select an I/O manager to use. + * + * This fills in the iomgr_type and rts_IOManagerIsWin32Native globals. + * Must be called before the I/O manager is started. + */ +static void selectIOManager(void) +{ + switch (RtsFlags.MiscFlags.ioManager) { + case IO_MNGR_FLAG_AUTO: +#if defined(THREADED_RTS) +#if defined(IOMGR_DEFAULT_THREADED_MIO) +#if defined(mingw32_HOST_OS) + iomgr_type = IO_MANAGER_MIO_WIN32; +#else + iomgr_type = IO_MANAGER_MIO_POSIX; +#endif +#elif defined(IOMGR_DEFAULT_THREADED_WINIO) + iomgr_type = IO_MANAGER_WINIO; +#else +#error No I/O default manager. See IOMGR_DEFAULT_THREADED_ flags +#endif +#else // !defined(THREADED_RTS) +#if defined(IOMGR_DEFAULT_NON_THREADED_SELECT) + iomgr_type = IO_MANAGER_SELECT; +#elif defined(IOMGR_DEFAULT_NON_THREADED_WINIO) + iomgr_type = IO_MANAGER_WINIO; +#elif defined(IOMGR_DEFAULT_NON_THREADED_WIN32_LEGACY) + iomgr_type = IO_MANAGER_WIN32_LEGACY; +#else +#error No I/O default manager. See IOMGR_DEFAULT_NON_THREADED_ flags +#endif +#endif + break; + +#if defined(IOMGR_ENABLED_SELECT) + case IO_MNGR_FLAG_SELECT: + iomgr_type = IO_MANAGER_SELECT; + break; +#endif + +#if defined(IOMGR_ENABLED_MIO_POSIX) + case IO_MNGR_FLAG_MIO: + iomgr_type = IO_MANAGER_MIO_POSIX; + break; +#endif + +#if defined(IOMGR_ENABLED_MIO_WIN32) + case IO_MNGR_FLAG_MIO: + iomgr_type = IO_MANAGER_MIO_WIN32; + break; +#endif + +#if defined(IOMGR_ENABLED_WINIO) + case IO_MNGR_FLAG_WINIO: + iomgr_type = IO_MANAGER_WINIO; + rts_IOManagerIsWin32Native = true; + break; +#endif + +#if defined(IOMGR_ENABLED_WIN32_LEGACY) + case IO_MNGR_FLAG_WIN32_LEGACY: + iomgr_type = IO_MANAGER_WIN32_LEGACY; + break; +#endif + + default: + barf("selectIOManager: %d", RtsFlags.MiscFlags.ioManager); + } +} + /* Allocate and initialise the per-capability CapIOManager that lives in each * Capability. Called early in the RTS initialisation. @@ -62,6 +230,7 @@ void initCapabilityIOManager(CapIOManager **piomgr) void initIOManager(void) { + selectIOManager(); #if defined(THREADED_RTS) /* Posix implementation in posix/Signals.c @@ -217,3 +386,18 @@ void insertIntoSleepingQueue(Capability *cap, StgTSO *tso, LowResTime target) } } #endif + +/* Temporary compat helper function used in the Win32 I/O managers. + * TODO: replace by consulting the iomgr_type global instead. + */ +bool is_io_mng_native_p (void) +{ + switch (iomgr_type) { +#if defined(IOMGR_ENABLED_WINIO) + case IO_MANAGER_WINIO: + return true; +#endif + default: + return false; + } +} diff --git a/rts/IOManager.h b/rts/IOManager.h index df5f72cdd840c0135673541f56b82d7fc0a026b9..1e34d6b16650391229216529794aa425ce7e00e0 100644 --- a/rts/IOManager.h +++ b/rts/IOManager.h @@ -122,6 +122,60 @@ IOMGR_ENABLED_STR_WINIO \ IOMGR_ENABLED_STR_WIN32_LEGACY +/* An enumeration of all the available I/O managers. We use conditional + * compilation to help us optimise out unavailable choices. To help us + * do that correctly, we only define choices that are available. + */ +typedef enum { +#if defined(IOMGR_ENABLED_SELECT) + IO_MANAGER_SELECT, +#endif +#if defined(IOMGR_ENABLED_MIO_POSIX) + IO_MANAGER_MIO_POSIX, +#endif +#if defined(IOMGR_ENABLED_MIO_WIN32) + IO_MANAGER_MIO_WIN32, +#endif +#if defined(IOMGR_ENABLED_WINIO) + IO_MANAGER_WINIO, +#endif +#if defined(IOMGR_ENABLED_WIN32_LEGACY) + IO_MANAGER_WIN32_LEGACY, +#endif +} IOManagerType; + +/* Global var to tell us which I/O manager impl we are using */ +extern IOManagerType iomgr_type; + +#if defined(mingw32_HOST_OS) +/* Global var (only on Windows) that is exported to be shared with the I/O code + * in the base library to tell us which style of I/O manager we are using: one + * that uses the Windows native API HANDLEs, or one that uses Posix style fds. + */ +extern bool rts_IOManagerIsWin32Native; +#endif + + +/* Parse the I/O manager flag value, returning if is available, unavailable or + * unrecognised. + * + * If it is available, the passed-in IO_MANAGER_FLAG value will be filled in + * to record what was requested. + * + * Called in the RTS flag processing by procRtsOpts. + */ +enum IOManagerAvailability { + IOManagerAvailable, + IOManagerUnavailable, + IOManagerUnrecognised +}; +enum IOManagerAvailability +parseIOManagerFlag(const char *iomgrstr, IO_MANAGER_FLAG *flag); + +/* Temporary compat helper function used in the Win32 I/O managers. + * TODO: replace by consulting the iomgr_type global instead. + */ +bool is_io_mng_native_p (void); /* The per-capability data structures belonging to the I/O manager. * diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c index 9e26df76f5e0ebb9ec72e7d5445b287a8fddd2df..e74499954badb1c1497fc39b5ba6c674f23c571d 100644 --- a/rts/RtsFlags.c +++ b/rts/RtsFlags.c @@ -269,11 +269,7 @@ void initRtsFlagsDefaults(void) RtsFlags.MiscFlags.internalCounters = false; RtsFlags.MiscFlags.linkerAlwaysPic = DEFAULT_LINKER_ALWAYS_PIC; RtsFlags.MiscFlags.linkerMemBase = 0; -#if defined(DEFAULT_NATIVE_IO_MANAGER) - RtsFlags.MiscFlags.ioManager = IO_MNGR_NATIVE; -#else - RtsFlags.MiscFlags.ioManager = IO_MNGR_POSIX; -#endif + RtsFlags.MiscFlags.ioManager = IO_MNGR_FLAG_AUTO; #if defined(THREADED_RTS) && defined(mingw32_HOST_OS) RtsFlags.MiscFlags.numIoWorkerThreads = getNumberOfProcessors(); #else @@ -533,8 +529,10 @@ usage_text[] = { " fatal error. When symbols are available an attempt will be", " made to resolve addresses to names. (default: yes)", #endif -" --io-manager=<native|posix>", -" The I/O manager subsystem to use. (default: posix)", +" --io-manager=<name>", +" The I/O manager to use.", +" Options available: auto" IOMGRS_ENABLED_STR + " (default: " IOMGR_DEFAULT_STR ")", #if defined(THREADED_RTS) #if defined(mingw32_HOST_OS) " --io-manager-threads=<num>", @@ -1013,15 +1011,23 @@ error = true; OPTION_SAFE; RtsFlags.MiscFlags.internalCounters = true; } - else if (strequal("io-manager=native", - &rts_argv[arg][2])) { - OPTION_UNSAFE; - RtsFlags.MiscFlags.ioManager = IO_MNGR_NATIVE; - } - else if (strequal("io-manager=posix", - &rts_argv[arg][2])) { + else if (!strncmp("io-manager=", + &rts_argv[arg][2], 11)) { OPTION_UNSAFE; - RtsFlags.MiscFlags.ioManager = IO_MNGR_POSIX; + char *iomgrstr = &rts_argv[arg][13]; + IO_MANAGER_FLAG iomgrflag; + enum IOManagerAvailability availability; + availability = parseIOManagerFlag(iomgrstr, &iomgrflag); + if (availability == IOManagerAvailable) { + RtsFlags.MiscFlags.ioManager = iomgrflag; + } else { + errorBelch("%s choice '%s' for --io-manager=\n" + "The choices are: auto%s", + availability == IOManagerUnavailable ? + "unavailable" : "unrecognised", + iomgrstr, IOMGRS_ENABLED_STR); + stg_exit(EXIT_FAILURE); + } } else if (strequal("info", &rts_argv[arg][2])) { @@ -2722,16 +2728,6 @@ files like <progname>.eventlog, not arbitrary files. Helper utilities to query state. ------------------------------------------------------------------------- */ -bool is_io_mng_native_p (void) -{ -#if defined(mingw32_HOST_OS) - return RtsFlags.MiscFlags.ioManager == IO_MNGR_NATIVE; -#else - return false; -#endif -} - - #if defined(PROFILING) bool doingLDVProfiling( void ) diff --git a/rts/RtsFlags.h b/rts/RtsFlags.h index 05a00af4e773fa3b35f25c01a658e0c191fad22d..2395a03aaa07c63036df50d413fedcff3cd73fb4 100644 --- a/rts/RtsFlags.h +++ b/rts/RtsFlags.h @@ -23,7 +23,6 @@ char** getUTF8Args(int* argc); void initRtsFlagsDefaults (void); void setupRtsFlags (int *argc, char *argv[], RtsConfig rtsConfig); void freeRtsArgs (void); -bool is_io_mng_native_p (void); #if defined(PROFILING) bool doingLDVProfiling (void); bool doingRetainerProfiling(void); diff --git a/rts/RtsSymbols.c b/rts/RtsSymbols.c index 9b908ee227c0d147ec82aed5f6f5554e6a6f3db3..285049a3066cc4cb2d401bfa463d16810924d88c 100644 --- a/rts/RtsSymbols.c +++ b/rts/RtsSymbols.c @@ -28,6 +28,7 @@ #include <io.h> #include <windows.h> #include <shfolder.h> /* SHGetFolderPathW */ +#include "IOManager.h" #include "win32/AsyncWinIO.h" #endif @@ -166,6 +167,7 @@ extern char **environ; SymI_HasProto(stg_asyncWritezh) \ SymI_HasProto(stg_asyncDoProczh) \ SymI_HasProto(rts_InstallConsoleEvent) \ + SymI_HasProto(rts_IOManagerIsWin32Native) \ SymI_HasProto(rts_ConsoleHandlerDone) \ SymI_NeedsProto(__mingw_module_is_dll) \ RTS_WIN32_ONLY(SymI_NeedsProto(___chkstk_ms)) \ diff --git a/rts/configure.ac b/rts/configure.ac index d1ae16fe407c638edf7369ef60d8dfb31fd43f13..5819e68d29b8952da403df84d3dd335e017c362b 100644 --- a/rts/configure.ac +++ b/rts/configure.ac @@ -37,16 +37,6 @@ if test "$enable_asserts_all_ways" = "yes" ; then AC_DEFINE([USE_ASSERTS_ALL_WAYS], [1], [Compile-in ASSERTs in all ways.]) fi -AC_ARG_ENABLE(native-io-manager, -[AS_HELP_STRING([--enable-native-io-manager], - [Enable the native I/O manager by default.])], - [FP_CAPITALIZE_YES_NO(["$enableval"], [EnableNativeIOManager])], - [EnableNativeIOManager=NO] -) -if test "$EnableNativeIOManager" = "YES"; then - AC_DEFINE_UNQUOTED([DEFAULT_NATIVE_IO_MANAGER], [1], [Enable Native I/O manager as default.]) -fi - # We have to run these unconditionally, but we may discard their # results in the following code AC_CANONICAL_BUILD diff --git a/rts/include/rts/Flags.h b/rts/include/rts/Flags.h index 66f8fa568ecf98669230619de908145cc9c64b1e..ca9520ef8a88c451cf4d9b28d04e41f153e8bdda 100644 --- a/rts/include/rts/Flags.h +++ b/rts/include/rts/Flags.h @@ -233,8 +233,22 @@ typedef struct _CONCURRENT_FLAGS { #define DEFAULT_LINKER_ALWAYS_PIC false #endif -/* Which I/O Manager to use in the target program. */ -typedef enum _IO_MANAGER { IO_MNGR_NATIVE, IO_MNGR_POSIX } IO_MANAGER; +/* Which I/O Manager to use in the target program. */ +typedef enum _IO_MANAGER_FLAG { + + /* Select an I/O manager automatically. This will pick the one determined + * at configure time, for the RTS way. This can also fall back to other + * available I/O managers if the first choice cannot be initialised, + * if platform support turns out to be unavailable (e.g. too old a kernel). + */ + IO_MNGR_FLAG_AUTO, + + /* All other choices pick only the requested one, with no fallback. */ + IO_MNGR_FLAG_SELECT, /* Unix only, non-threaded RTS only */ + IO_MNGR_FLAG_MIO, /* cross-platform, threaded RTS only */ + IO_MNGR_FLAG_WINIO, /* Windows only */ + IO_MNGR_FLAG_WIN32_LEGACY, /* Windows only, non-threaded RTS only */ + } IO_MANAGER_FLAG; /* See Note [Synchronization of flags and base APIs] */ typedef struct _MISC_FLAGS { @@ -254,7 +268,7 @@ typedef struct _MISC_FLAGS { bool linkerAlwaysPic; /* Assume the object code is always PIC */ StgWord linkerMemBase; /* address to ask the OS for memory * for the linker, NULL ==> off */ - IO_MANAGER ioManager; /* The I/O manager to use. */ + IO_MANAGER_FLAG ioManager; /* The I/O manager to use. */ uint32_t numIoWorkerThreads; /* Number of I/O worker threads to use. */ } MISC_FLAGS;