Skip to content
Snippets Groups Projects
Commit 15f4d867 authored by Duncan Coutts's avatar Duncan Coutts Committed by Marge Bot
Browse files

Initial ./configure support for selecting I/O managers


In this patch we just define new CPP vars, but don't yet use them
or replace the existing approach. That will follow.

The intention here is that every I/O manager can be enabled/disabled at
GHC build time (subject to some constraints). More than one I/O manager
can be enabled to be built. At least one I/O manager supporting the
non-threaded RTS must be enabled as well as at least one supporting the
non-threaded RTS. The I/O managers enabled here will become the choices
available at runtime at RTS startup (in later patches). The choice can
be made with RTS flags. There are separate sets of choices for the
threaded and non-threaded RTS ways, because most I/O managers are
specific to these ways. Furthermore we must establish a default I/O
manager for the threaded and non-threaded RTS.

Most I/O managers are platform-specific so there are checks to ensure
each one can be enabled on the platform. Such checks are also where (in
future) any system dependencies (e.g. libraries) can be checked.

The output is a set of CPP flags (in the mk/config.h file), with one
flag per named I/O manager:
* IOMGR_BUILD_<name>                : which ones should be built (some)
* IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one)
* IOMGR_DEFAULT_THREADED_<name>     : which one is default (exactly one)

and a set of derived flags in IOManager.h

* IOMGR_ENABLED_<name>              : enabled for the current RTS way

Note that IOMGR_BUILD_<name> just says that an I/O manager will be
built for _some_ RTS way (i.e. threaded or non-threaded). The derived
flags IOMGR_ENABLED_<name> in IOManager.h say if each I/O manager is
enabled in the "current" RTS way. These are the ones that can be used
for conditional compilation of the I/O manager code.

Co-authored-by: default avatarPi Delport <pi@well-typed.com>
parent e0b0c717
No related branches found
No related tags found
No related merge requests found
# GHC_IOMANAGER_ENABLE(iomgr_name, enable_var, output_cpp_var, action_detect)
# ---------------------------------------------------------------------
AC_DEFUN([GHC_IOMANAGER_ENABLE], [
$4
AC_MSG_CHECKING( if the the $1 I/O manager should be built)
if test "${$2}" = "YES"; then
AC_MSG_RESULT(yes)
AC_DEFINE([$3], [1], [Define to 1 if the $1 I/O manager should be built])
else
AC_MSG_RESULT(no)
fi
])
# GHC_IOMANAGER_DEFAULT_SELECT(default_var, iomgr_name, enable_var)
# ---------------------------------------------------------------------
AC_DEFUN([GHC_IOMANAGER_DEFAULT_SELECT], [
if test "${$3}" = "YES"; then
$1=$2
fi
])
# GHC_IOMANAGER_DEFAULT_CHECK_NOT_EMPTY(default_var, way)
# ---------------------------------------------------------------------
AC_DEFUN([GHC_IOMANAGER_DEFAULT_CHECK_NOT_EMPTY], [
if test "${$1}" = ""; then
AC_MSG_ERROR([no suitable I/O manager enabled for the $2 RTS])
fi
])
# GHC_IOMANAGER_DEFAULT_AC_DEFINE(default_var, way, iomgr_name, output_cpp_var)
# ---------------------------------------------------------------------
AC_DEFUN([GHC_IOMANAGER_DEFAULT_AC_DEFINE], [
if test "${$1}" = "$3"; then
AC_DEFINE([$4], [1],
[Define to 1 if the $3 I/O manager is the default for the $2 RTS])
fi
])
......@@ -24,6 +24,104 @@
#include "sm/GC.h" // for evac_fn
#include "posix/Select.h" // for LowResTime TODO: switch to normal Time
/* The ./configure gives us a set of CPP flags, one for each named I/O manager:
* IOMGR_BUILD_<name> : which ones should be built (some)
* IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one)
* IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one)
*
* The IOMGR_BUILD_<name> flags just says that an I/O manager should be built
* for _some_ RTS way (i.e. threaded or non-threaded). What we need however are
* flags to use for conditional compilation of I/O manager code. These flags
* must take into account whether the particular I/O manager is enabled for the
* RTS way we're currently building, in particular taking into account if we're
* building for a threaded or non-threaded RTS.
*
* So here we define a set of derived flags IOMGR_ENABLED_<name> which says if
* each I/O manager is enabled in the RTS way we're building now. We'll then
* use these flags everywhere else for conditional compilation.
*/
#if defined(IOMGR_BUILD_SELECT) && !defined(THREADED_RTS)
#define IOMGR_ENABLED_SELECT
#endif
#if defined(IOMGR_BUILD_MIO) && defined(THREADED_RTS)
/* For MIO, it is really two separate I/O manager implementations: one for
* Windows and one for non-Windows. This is clear from both the C code on the
* RTS side and the Haskell code in the base library. By treating them as
* such leads to simpler I/O manager dispatch code.
*
* These two implementations do share a common architecture, and so we still
* use a single name in public interfaces like ./configure and the RTS flags.
*/
#if defined(mingw32_HOST_OS)
#define IOMGR_ENABLED_MIO_WIN32
#else
#define IOMGR_ENABLED_MIO_POSIX
#endif
#endif
#if defined(IOMGR_BUILD_WINIO)
#define IOMGR_ENABLED_WINIO
#endif
#if defined(IOMGR_BUILD_WIN32_LEGACY) && !defined(THREADED_RTS)
#define IOMGR_ENABLED_WIN32_LEGACY
#endif
/* To provide a string to use for output of +RTS -? we use the
* IOMGR_DEFAULT_{NON_}THREADED_<name> flags to derived a CPP variable
* IOMGR_DEFAULT_STR with the string name of the default I/O manager for the
* _current_ RTS way. At the same time we can do a sanity check that there is
* actually a default.
*/
#if defined(THREADED_RTS)
#if defined(IOMGR_DEFAULT_THREADED_MIO)
#define IOMGR_DEFAULT_STR "mio"
#elif defined(IOMGR_DEFAULT_THREADED_WINIO)
#define IOMGR_DEFAULT_STR "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)
#define IOMGR_DEFAULT_STR "select"
#elif defined(IOMGR_DEFAULT_NON_THREADED_WINIO)
#define IOMGR_DEFAULT_STR "winio"
#elif defined(IOMGR_DEFAULT_NON_THREADED_WIN32_LEGACY)
#define IOMGR_DEFAULT_STR "win32-legacy"
#else
#error No I/O default manager. See IOMGR_DEFAULT_NON_THREADED_ flags
#endif
#endif
/* To help with error messages we provide a macro IOMGRS_ENABLED_STR that is
* the stringy list of all enabled I/O managers (with leading and separating
* spaces)
*/
#if defined(IOMGR_ENABLED_SELECT)
#define IOMGR_ENABLED_STR_SELECT " select"
#else
#define IOMGR_ENABLED_STR_SELECT ""
#endif
#if defined(IOMGR_ENABLED_MIO_POSIX) || defined(IOMGR_ENABLED_MIO_WIN32)
#define IOMGR_ENABLED_STR_MIO " mio"
#else
#define IOMGR_ENABLED_STR_MIO ""
#endif
#if defined(IOMGR_ENABLED_WINIO)
#define IOMGR_ENABLED_STR_WINIO " winio"
#else
#define IOMGR_ENABLED_STR_WINIO ""
#endif
#if defined(IOMGR_ENABLED_WIN32_LEGACY)
#define IOMGR_ENABLED_STR_WIN32_LEGACY " win32-legacy"
#else
#define IOMGR_ENABLED_STR_WIN32_LEGACY ""
#endif
#define IOMGRS_ENABLED_STR \
IOMGR_ENABLED_STR_SELECT \
IOMGR_ENABLED_STR_MIO \
IOMGR_ENABLED_STR_WINIO \
IOMGR_ENABLED_STR_WIN32_LEGACY
/* The per-capability data structures belonging to the I/O manager.
*
......
......@@ -351,6 +351,93 @@ AS_IF(
[test "$CABAL_FLAG_libnuma" = 1],
[AC_CHECK_HEADERS([numa.h numaif.h])])
dnl ** I/O managers
dnl --------------------------------------------------------------
dnl
dnl The scheme here is that every I/O manager can be enabled/disabled
dnl at GHC build time (subject to some constraints). More than one I/O
dnl manager can be enabled to be built. At least one I/O manager
dnl supporting the threaded RTS must be enabled as well as at least
dnl one supporting the non-threaded RTS. The I/O managers enabled here
dnl become the choices available at runtime at RTS startup. The choice
dnl can be made with RTS flags. There are separate choices for the
dnl threaded and non-threaded RTS ways, because most I/O managers are
dnl specific to these ways. Furthermore we must establish a default I/O
dnl manager for the threaded and non-threaded RTS.
dnl
dnl Most I/O managers are platform-specific so there are checks to
dnl ensure each one can be enabled on the platform. Such checks are
dnl also where any system dependencies (e.g. libraries) can be checked.
dnl
dnl The output is a set of CPP flags, with one flag per named I/O manager:
dnl * IOMGR_BUILD_<name> : which ones should be built (some)
dnl * IOMGR_DEFAULT_NON_THREADED_<name> : which one is default (exactly one)
dnl * IOMGR_DEFAULT_THREADED_<name> : which one is default (exactly one)
dnl
dnl Note that IOMGR_BUILD_<name> just says that an I/O manager will be
dnl built for _some_ RTS way (i.e. threaded or non-threaded). There is
dnl a set of derived flags IOMGR_ENABLED_<name> in IOManager.h which says
dnl if each I/O manager is enabled in the "current" RTS way. These are
dnl the ones used for conditional compilation of the I/O manager code.
dnl -------------------------------------------------------------------
dnl Here we check for platform constraints. The result is the CPP flag
dnl IOMGR_BUILD_<name> and a EnableIOManager<Name> var for use here later.
GHC_IOMANAGER_ENABLE([select], [EnableIOManagerSelect], [IOMGR_BUILD_SELECT],
[if test "$HostOS" = "mingw32"; then
EnableIOManagerSelect=NO
else
AC_CHECK_HEADER([sys/select.h],
[EnableIOManagerSelect=YES],
[AC_MSG_ERROR([sys/select.h required by select I/O manager])],[])
fi])
GHC_IOMANAGER_ENABLE([mio], [EnableIOManagerMIO], [IOMGR_BUILD_MIO],
[EnableIOManagerMIO=YES])
GHC_IOMANAGER_ENABLE([win32-legacy], [EnableIOManagerWin32Legacy], [IOMGR_BUILD_WIN32_LEGACY],
[if test "$HostOS" = "mingw32"; then EnableIOManagerWin32Legacy=YES; fi])
GHC_IOMANAGER_ENABLE([winio], [EnableIOManagerWinIO], [IOMGR_BUILD_WINIO],
[if test "$HostOS" = "mingw32"; then EnableIOManagerWinIO=YES; fi])
dnl Now we establish a default I/O manager for the threaded and non-threaded
dnl RTS. We select the default based on which I/O managers are enabled. They
dnl are checked in reverse order of priority, the last enabled one wins:
if test "$HostOS" = "mingw32"; then
GHC_IOMANAGER_DEFAULT_SELECT([IOManagerNonThreadedDefault], [winio], [EnableIOManagerWinIO],)
GHC_IOMANAGER_DEFAULT_SELECT([IOManagerNonThreadedDefault], [win32-legacy], [EnableIOManagerWin32Legacy])
GHC_IOMANAGER_DEFAULT_SELECT([IOManagerThreadedDefault], [winio], [EnableIOManagerWinIO])
GHC_IOMANAGER_DEFAULT_SELECT([IOManagerThreadedDefault], [mio], [EnableIOManagerMIO])
else
GHC_IOMANAGER_DEFAULT_SELECT([IOManagerNonThreadedDefault], [select], [EnableIOManagerSelect])
GHC_IOMANAGER_DEFAULT_SELECT([IOManagerThreadedDefault], [mio], [EnableIOManagerMIO])
fi
GHC_IOMANAGER_DEFAULT_CHECK_NOT_EMPTY([IOManagerNonThreadedDefault],[non-threaded])
GHC_IOMANAGER_DEFAULT_CHECK_NOT_EMPTY([IOManagerThreadedDefault],[threaded])
AC_MSG_NOTICE(default I/O manager for the non-threaded RTS: ${IOManagerNonThreadedDefault})
AC_MSG_NOTICE(default I/O manager for the threaded RTS: ${IOManagerThreadedDefault})
dnl Now define CPP vars for the default ones (threaded and non-threaded)
GHC_IOMANAGER_DEFAULT_AC_DEFINE([IOManagerNonThreadedDefault], [non-threaded],
[select], [IOMGR_DEFAULT_NON_THREADED_SELECT])
GHC_IOMANAGER_DEFAULT_AC_DEFINE([IOManagerNonThreadedDefault], [non-threaded],
[winio], [IOMGR_DEFAULT_NON_THREADED_WINIO])
GHC_IOMANAGER_DEFAULT_AC_DEFINE([IOManagerNonThreadedDefault], [non-threaded],
[win32-legacy], [IOMGR_DEFAULT_NON_THREADED_WIN32_LEGACY])
GHC_IOMANAGER_DEFAULT_AC_DEFINE([IOManagerThreadedDefault], [threaded],
[mio], [IOMGR_DEFAULT_THREADED_MIO])
GHC_IOMANAGER_DEFAULT_AC_DEFINE([IOManagerThreadedDefault], [threaded],
[winio], [IOMGR_DEFAULT_THREADED_WINIO])
dnl ** Write config files
dnl --------------------------------------------------------------
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment