[commit: ghc] ghc-7.8: Revert "Revert "rts/base: Fix #9423"" and resolve issue that caused the revert. (55d2522)

git at git.haskell.org git at git.haskell.org
Wed Nov 5 19:02:25 UTC 2014


Repository : ssh://git@git.haskell.org/ghc

On branch  : ghc-7.8
Link       : http://ghc.haskell.org/trac/ghc/changeset/55d2522bd0c48e4c5dac1526cdf53459270baf96/ghc

>---------------------------------------------------------------

commit 55d2522bd0c48e4c5dac1526cdf53459270baf96
Author: Andreas Voellmy <andreas.voellmy at gmail.com>
Date:   Wed Nov 5 13:02:20 2014 -0600

    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
    
    (commit cherry picked from 7e658bc14e2dd6baf208deebbdab9e1285ce4c72)


>---------------------------------------------------------------

55d2522bd0c48e4c5dac1526cdf53459270baf96
 includes/rts/IOManager.h |  3 +-
 rts/Capability.c         | 19 +++++++++++
 rts/Capability.h         |  4 +++
 rts/Linker.c             |  1 +
 rts/posix/Signals.c      | 86 +++++++++++++++++++++++++++++-------------------
 5 files changed, 79 insertions(+), 34 deletions(-)

diff --git a/includes/rts/IOManager.h b/includes/rts/IOManager.h
index 1c331b9..7bf2cdf 100644
--- a/includes/rts/IOManager.h
+++ b/includes/rts/IOManager.h
@@ -26,7 +26,8 @@ void     sendIOManagerEvent (HsWord32 event);
 
 #else
 
-void     setIOManagerControlFd   (int fd);
+void     setIOManagerControlFd   (nat cap_no, int fd);
+void     setTimerManagerControlFd(int fd);
 void     setIOManagerWakeupFd   (int fd);
 
 #endif
diff --git a/rts/Capability.c b/rts/Capability.c
index 16b71b7..87c5950 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;
 
@@ -1073,3 +1080,15 @@ 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
diff --git a/rts/Capability.h b/rts/Capability.h
index f342d92..fc2bdb0 100644
--- a/rts/Capability.h
+++ b/rts/Capability.h
@@ -121,6 +121,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 ceb6a4f..124f6cc 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -858,6 +858,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 f4a8341..a6978e6 100644
--- a/rts/posix/Signals.c
+++ b/rts/posix/Signals.c
@@ -124,28 +124,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)
 {
@@ -167,14 +166,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;
+        }
     }
 }
 
@@ -189,10 +198,10 @@ ioManagerStart (void)
 {
     // Make sure the IO manager thread is running
     Capability *cap;
-    if (io_manager_control_fd < 0 || io_manager_wakeup_fd < 0) {
-	cap = rts_lock();
+    if (timer_manager_control_wr_fd < 0 || io_manager_wakeup_fd < 0) {
+        cap = rts_lock();
         ioManagerStartCap(&cap);
-	rts_unlock(cap);
+        rts_unlock(cap);
     }
 }
 #endif
@@ -220,26 +229,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;
-
-        buf[0] = sig;
+    StgWord8 buf[sizeof(siginfo_t) + 1];
+    int r;
 
-	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));
-	}
+    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));
+    }
 
-	r = write(io_manager_control_fd, buf, sizeof(siginfo_t)+1);
-        if (r == -1 && errno == EAGAIN)
-        {
+    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);
         }
     }
+
+    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..



More information about the ghc-commits mailing list