diff options
author | Duncan Coutts <duncan@well-typed.com> | 2020-12-28 23:24:44 +0000 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2022-11-22 02:06:16 -0500 |
commit | 8d6aaa49e011ec58f88b65a50a90f64bfd0a1f60 (patch) | |
tree | 41612b1a3ab9ee0f3ae9d77611d08d1807818263 | |
parent | 451aeac3b07f171f148995717d0d9a1eefe08f0e (diff) | |
download | haskell-8d6aaa49e011ec58f88b65a50a90f64bfd0a1f60.tar.gz |
Introduce CapIOManager as the per-cap I/O mangager state
Rather than each I/O manager adding things into the Capability structure
ad-hoc, we should have a common CapIOManager iomgr member of the
Capability structure, with a common interface to initialise etc.
The content of the CapIOManager struct will be defined differently for
each I/O manager implementation. Eventually we should be able to have
the CapIOManager be opaque to the rest of the RTS, and known just to the
I/O manager implementation. We plan for that by making the Capability
contain a pointer to the CapIOManager rather than containing the
structure directly.
Initially just move the Unix threaded I/O manager's control FD.
-rw-r--r-- | rts/Capability.c | 5 | ||||
-rw-r--r-- | rts/Capability.h | 8 | ||||
-rw-r--r-- | rts/IOManager.c | 22 | ||||
-rw-r--r-- | rts/IOManager.h | 33 | ||||
-rw-r--r-- | rts/posix/Signals.c | 4 |
5 files changed, 60 insertions, 12 deletions
diff --git a/rts/Capability.c b/rts/Capability.c index c3571f6d64..05332514e3 100644 --- a/rts/Capability.c +++ b/rts/Capability.c @@ -278,12 +278,11 @@ initCapability (Capability *cap, uint32_t i) cap->spark_stats.converted = 0; cap->spark_stats.gcd = 0; cap->spark_stats.fizzled = 0; -#if !defined(mingw32_HOST_OS) - cap->io_manager_control_wr_fd = -1; -#endif #endif cap->total_allocated = 0; + initCapabilityIOManager(&cap->iomgr); + cap->f.stgEagerBlackholeInfo = (W_)&__stg_EAGER_BLACKHOLE_info; cap->f.stgGCEnter1 = (StgFunPtr)__stg_gc_enter_1; cap->f.stgGCFun = (StgFunPtr)__stg_gc_fun; diff --git a/rts/Capability.h b/rts/Capability.h index 1f3ff95736..884d281fa2 100644 --- a/rts/Capability.h +++ b/rts/Capability.h @@ -24,6 +24,7 @@ #include "Task.h" #include "Sparks.h" #include "sm/NonMovingMark.h" // for MarkQueue +#include "IOManager.h" // for CapIOManager #include "BeginPrivate.h" @@ -157,12 +158,11 @@ struct Capability_ { // Stats on spark creation/conversion SparkCounters spark_stats; -#if !defined(mingw32_HOST_OS) - // IO manager for this cap - int io_manager_control_wr_fd; -#endif #endif + // I/O manager data structures for this capability + CapIOManager *iomgr; + // Per-capability STM-related data StgTVarWatchQueue *free_tvar_watch_queues; StgTRecChunk *free_trec_chunks; diff --git a/rts/IOManager.c b/rts/IOManager.c index 6606b82e06..6782c3984d 100644 --- a/rts/IOManager.c +++ b/rts/IOManager.c @@ -20,6 +20,7 @@ #include "IOManager.h" // RTS internal #include "Capability.h" #include "RtsFlags.h" +#include "RtsUtils.h" #if !defined(mingw32_HOST_OS) && defined(HAVE_SIGNAL_H) #include "posix/Signals.h" @@ -32,7 +33,24 @@ #endif -/* Called in the RTS initialisation +/* Allocate and initialise the per-capability CapIOManager that lives in each + * Capability. Called early in the RTS initialisation. + */ +void initCapabilityIOManager(CapIOManager **piomgr) +{ + CapIOManager *iomgr = + (CapIOManager *) stgMallocBytes(sizeof(CapIOManager), + "initCapabilityIOManager"); + +#if defined(THREADED_RTS) && !defined(mingw32_HOST_OS) + iomgr->control_fd = -1; +#endif + + *piomgr = iomgr; +} + + +/* Called late in the RTS initialisation */ void initIOManager(void) @@ -140,7 +158,7 @@ void setIOManagerControlFd(uint32_t cap_no USED_IF_THREADS, int fd USED_IF_THREADS) { #if defined(THREADED_RTS) if (cap_no < n_capabilities) { - RELAXED_STORE(&capabilities[cap_no]->io_manager_control_wr_fd, fd); + RELAXED_STORE(&capabilities[cap_no]->iomgr->control_fd, fd); } else { errorBelch("warning: setIOManagerControlFd called with illegal capability number."); } diff --git a/rts/IOManager.h b/rts/IOManager.h index f7523149c3..ed7b4dcdcf 100644 --- a/rts/IOManager.h +++ b/rts/IOManager.h @@ -21,7 +21,38 @@ #include "BeginPrivate.h" -/* Init hook: called from hs_init_ghc. +/* The per-capability data structures belonging to the I/O manager. + * + * It can be accessed as cap->iomgr. + * + * The content of the structure is defined conditionally so it is different for + * each I/O manager implementation. + * + * TODO: once the content of this struct is genuinely private, and not shared + * with other parts of the RTS, then it can be made opaque, so the content is + * known only to the I/O manager and not the rest of the RTS. + */ +typedef struct { + +#if defined(THREADED_RTS) +#if !defined(mingw32_HOST_OS) + /* Control FD for the MIO manager for this capability */ + int control_fd; +#endif +#endif + +} CapIOManager; + + +/* Allocate and initialise the per-capability CapIOManager that lives in each + * Capability. It is called from initCapability, via initScheduler, + * via hs_init_ghc. + */ +void initCapabilityIOManager(CapIOManager **iomgr); + + +/* Init hook: called from hs_init_ghc, very late in the startup after almost + * everything else is done. */ void initIOManager(void); diff --git a/rts/posix/Signals.c b/rts/posix/Signals.c index 95a7853e37..7d58f3d7a2 100644 --- a/rts/posix/Signals.c +++ b/rts/posix/Signals.c @@ -203,11 +203,11 @@ ioManagerDie (void) { // Shut down IO managers for (i=0; i < n_capabilities; i++) { - const int fd = RELAXED_LOAD(&capabilities[i]->io_manager_control_wr_fd); + const int fd = RELAXED_LOAD(&capabilities[i]->iomgr->control_fd); if (0 <= fd) { r = write(fd, &byte, 1); if (r == -1) { sysErrorBelch("ioManagerDie: write"); } - RELAXED_STORE(&capabilities[i]->io_manager_control_wr_fd, -1); + RELAXED_STORE(&capabilities[i]->iomgr->control_fd, -1); } } } |