summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
authorAndreas Voellmy <andreas.voellmy@gmail.com>2014-09-16 07:56:54 -0500
committerAustin Seipp <austin@well-typed.com>2014-09-16 07:58:36 -0500
commit7e658bc14e2dd6baf208deebbdab9e1285ce4c72 (patch)
tree526c6557dd697360c4bc58ff99ecdf6b60c046ed /rts
parentcaf449e39f5e7545eeabd567349661450aa8c6e5 (diff)
downloadhaskell-7e658bc14e2dd6baf208deebbdab9e1285ce4c72.tar.gz
Revert "Revert "rts/base: Fix #9423"" and resolve issue that caused the revert.
Summary: This reverts commit 4748f5936fe72d96edfa17b153dbfd84f2c4c053. The fix for #9423 was reverted because this commit introduced a C function setIOManagerControlFd() (defined in Schedule.c) defined for all OS types, while the prototype (in includes/rts/IOManager.h) was only included when mingw32_HOST_OS is not defined. This broke Windows builds. This commit reverts the original commit and resolves the problem by only defining setIOManagerControlFd() when mingw32_HOST_OS is defined. Hence the missing prototype error should not occur on Windows. In addition, since the io_manager_control_wr_fd field of the Capability struct is only usd by the setIOManagerControlFd, this commit includes the io_manager_control_wr_fd field in the Capability struct only when mingw32_HOST_OS is not defined. Test Plan: Try to compile successfully on all platforms. Reviewers: austin Reviewed By: austin Subscribers: simonmar, ezyang, carter Differential Revision: https://phabricator.haskell.org/D174
Diffstat (limited to 'rts')
-rw-r--r--rts/Capability.c19
-rw-r--r--rts/Capability.h4
-rw-r--r--rts/Linker.c1
-rw-r--r--rts/posix/Signals.c80
4 files changed, 74 insertions, 30 deletions
diff --git a/rts/Capability.c b/rts/Capability.c
index 29c5270416..a954006257 100644
--- a/rts/Capability.c
+++ b/rts/Capability.c
@@ -27,6 +27,10 @@
#include "STM.h"
#include "RtsUtils.h"
+#if !defined(mingw32_HOST_OS)
+#include "rts/IOManager.h" // for setIOManagerControlFd()
+#endif
+
#include <string.h>
// one global capability, this is the Capability for non-threaded
@@ -255,6 +259,9 @@ initCapability( Capability *cap, nat 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;
@@ -1076,6 +1083,18 @@ rtsBool checkSparkCountInvariant (void)
}
#endif
+#if !defined(mingw32_HOST_OS)
+void setIOManagerControlFd(nat cap_no USED_IF_THREADS, int fd USED_IF_THREADS) {
+#if defined(THREADED_RTS)
+ if (cap_no < n_capabilities) {
+ capabilities[cap_no]->io_manager_control_wr_fd = fd;
+ } else {
+ errorBelch("warning: setIOManagerControlFd called with illegal capability number.");
+ }
+#endif
+}
+#endif
+
// Local Variables:
// mode: C
// fill-column: 80
diff --git a/rts/Capability.h b/rts/Capability.h
index c7dceefe9f..9a6651e0e6 100644
--- a/rts/Capability.h
+++ b/rts/Capability.h
@@ -126,6 +126,10 @@ 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
// Total words allocated by this cap since rts start
W_ total_allocated;
diff --git a/rts/Linker.c b/rts/Linker.c
index b24be580b4..dba346eb86 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -860,6 +860,7 @@ typedef struct _RtsSymbolVal {
#if !defined(mingw32_HOST_OS)
#define RTS_USER_SIGNALS_SYMBOLS \
SymI_HasProto(setIOManagerControlFd) \
+ SymI_HasProto(setTimerManagerControlFd) \
SymI_HasProto(setIOManagerWakeupFd) \
SymI_HasProto(ioManagerWakeup) \
SymI_HasProto(blockUserSignals) \
diff --git a/rts/posix/Signals.c b/rts/posix/Signals.c
index d5129f0996..ba4a8b75ea 100644
--- a/rts/posix/Signals.c
+++ b/rts/posix/Signals.c
@@ -127,28 +127,27 @@ more_handlers(int sig)
// Here's the pipe into which we will send our signals
static int io_manager_wakeup_fd = -1;
-static int io_manager_control_fd = -1;
+static int timer_manager_control_wr_fd = -1;
#define IO_MANAGER_WAKEUP 0xff
#define IO_MANAGER_DIE 0xfe
#define IO_MANAGER_SYNC 0xfd
-void
-setIOManagerWakeupFd (int fd)
-{
- // only called when THREADED_RTS, but unconditionally
- // compiled here because GHC.Event.Control depends on it.
- io_manager_wakeup_fd = fd;
+void setTimerManagerControlFd(int fd) {
+ timer_manager_control_wr_fd = fd;
}
void
-setIOManagerControlFd (int fd)
+setIOManagerWakeupFd (int fd)
{
// only called when THREADED_RTS, but unconditionally
// compiled here because GHC.Event.Control depends on it.
- io_manager_control_fd = fd;
+ io_manager_wakeup_fd = fd;
}
+/* -----------------------------------------------------------------------------
+ * Wake up at least one IO or timer manager HS thread.
+ * -------------------------------------------------------------------------- */
void
ioManagerWakeup (void)
{
@@ -170,14 +169,24 @@ ioManagerWakeup (void)
void
ioManagerDie (void)
{
+ StgWord8 byte = (StgWord8)IO_MANAGER_DIE;
+ nat i;
+ int fd;
int r;
- // Ask the IO Manager thread to exit
- if (io_manager_control_fd >= 0) {
- StgWord8 byte = (StgWord8)IO_MANAGER_DIE;
- r = write(io_manager_control_fd, &byte, 1);
+
+ if (0 <= timer_manager_control_wr_fd) {
+ r = write(timer_manager_control_wr_fd, &byte, 1);
if (r == -1) { sysErrorBelch("ioManagerDie: write"); }
- io_manager_control_fd = -1;
- io_manager_wakeup_fd = -1;
+ timer_manager_control_wr_fd = -1;
+ }
+
+ for (i=0; i < n_capabilities; i++) {
+ fd = capabilities[i]->io_manager_control_wr_fd;
+ if (0 <= fd) {
+ r = write(fd, &byte, 1);
+ if (r == -1) { sysErrorBelch("ioManagerDie: write"); }
+ capabilities[i]->io_manager_control_wr_fd = -1;
+ }
}
}
@@ -192,7 +201,7 @@ ioManagerStart (void)
{
// Make sure the IO manager thread is running
Capability *cap;
- if (io_manager_control_fd < 0 || io_manager_wakeup_fd < 0) {
+ if (timer_manager_control_wr_fd < 0 || io_manager_wakeup_fd < 0) {
cap = rts_lock();
ioManagerStartCap(&cap);
rts_unlock(cap);
@@ -223,26 +232,37 @@ generic_handler(int sig USED_IF_THREADS,
{
#if defined(THREADED_RTS)
- if (io_manager_control_fd != -1)
- {
- StgWord8 buf[sizeof(siginfo_t) + 1];
- int r;
+ StgWord8 buf[sizeof(siginfo_t) + 1];
+ int r;
- buf[0] = sig;
+ buf[0] = sig;
+ if (info == NULL) {
+ // info may be NULL on Solaris (see #3790)
+ memset(buf+1, 0, sizeof(siginfo_t));
+ } else {
+ memcpy(buf+1, info, sizeof(siginfo_t));
+ }
- if (info == NULL) {
- // info may be NULL on Solaris (see #3790)
- memset(buf+1, 0, sizeof(siginfo_t));
- } else {
- memcpy(buf+1, info, sizeof(siginfo_t));
+ if (0 <= timer_manager_control_wr_fd)
+ {
+ r = write(timer_manager_control_wr_fd, buf, sizeof(siginfo_t)+1);
+ if (r == -1 && errno == EAGAIN) {
+ errorBelch("lost signal due to full pipe: %d\n", sig);
}
+ }
- r = write(io_manager_control_fd, buf, sizeof(siginfo_t)+1);
- if (r == -1 && errno == EAGAIN)
- {
- errorBelch("lost signal due to full pipe: %d\n", sig);
+ nat i;
+ int fd;
+ for (i=0; i < n_capabilities; i++) {
+ fd = capabilities[i]->io_manager_control_wr_fd;
+ if (0 <= fd) {
+ r = write(fd, buf, sizeof(siginfo_t)+1);
+ if (r == -1 && errno == EAGAIN) {
+ errorBelch("lost signal due to full pipe: %d\n", sig);
+ }
}
}
+
// If the IO manager hasn't told us what the FD of the write end
// of its pipe is, there's not much we can do here, so just ignore
// the signal..