summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncan Coutts <duncan@well-typed.com>2020-12-28 23:24:44 +0000
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-11-22 02:06:16 -0500
commit8d6aaa49e011ec58f88b65a50a90f64bfd0a1f60 (patch)
tree41612b1a3ab9ee0f3ae9d77611d08d1807818263
parent451aeac3b07f171f148995717d0d9a1eefe08f0e (diff)
downloadhaskell-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.c5
-rw-r--r--rts/Capability.h8
-rw-r--r--rts/IOManager.c22
-rw-r--r--rts/IOManager.h33
-rw-r--r--rts/posix/Signals.c4
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);
}
}
}