Integrate new I/O manager, with signal support
authorJohan Tibell <johan.tibell@gmail.com>
Sat, 24 Jul 2010 10:23:55 +0000 (10:23 +0000)
committerJohan Tibell <johan.tibell@gmail.com>
Sat, 24 Jul 2010 10:23:55 +0000 (10:23 +0000)
configure.ac
includes/rts/Globals.h
includes/rts/IOManager.h
rts/Globals.c
rts/Linker.c
rts/Prelude.h
rts/package.conf.in
rts/posix/Signals.c
rts/win32/ThrIOManager.c
rts/win32/libHSbase.def

index 33614e0..3d05a0f 100644 (file)
@@ -878,6 +878,10 @@ AC_TRY_LINK_FUNC(printf\$LDBLStub,
             [Define to 1 if we have printf$LDBLStub (Apple Mac OS >= 10.4, PPC).])
     ])
 
+dnl ** check for eventfd which is needed by the I/O manager
+AC_CHECK_HEADERS([sys/eventfd.h])
+AC_CHECK_FUNCS([eventfd])
+
 # test for GTK+
 AC_PATH_PROGS([GTK_CONFIG], [pkg-config])
 if test -n "$GTK_CONFIG"; then
index 75c7f69..218b7ef 100644 (file)
 #define RTS_GLOBALS_H
 
 StgStablePtr getOrSetTypeableStore(StgStablePtr value);
-StgStablePtr getOrSetGHCConcSignalHandlerStore(StgStablePtr value);
-StgStablePtr getOrSetGHCConcPendingEventsStore(StgStablePtr ptr);
-StgStablePtr getOrSetGHCConcPendingDelaysStore(StgStablePtr ptr);
-StgStablePtr getOrSetGHCConcIOManagerThreadStore(StgStablePtr ptr);
-StgStablePtr getOrSetGHCConcProddingStore(StgStablePtr ptr);
+StgStablePtr getOrSetGHCConcSignalSignalHandlerStore(StgStablePtr value);
+StgStablePtr getOrSetGHCConcWindowsPendingDelaysStore(StgStablePtr ptr);
+StgStablePtr getOrSetGHCConcWindowsIOManagerThreadStore(StgStablePtr ptr);
+StgStablePtr getOrSetGHCConcWindowsProddingStore(StgStablePtr ptr);
+StgStablePtr getOrSetSystemEventThreadEventManagerStore(StgStablePtr ptr);
+StgStablePtr getOrSetSystemEventThreadIOManagerThreadStore(StgStablePtr ptr);
 
 #endif /* RTS_GLOBALS_H */
index 3aedda8..bf93d97 100644 (file)
@@ -26,8 +26,8 @@ void     sendIOManagerEvent (HsWord32 event);
 
 #else
 
-void     setIOManagerPipe   (int fd);
-void     ioManagerSync (void);
+void     setIOManagerControlFd   (int fd);
+void     setIOManagerWakeupFd   (int fd);
 
 #endif
 
index 01d8a8f..7b8967f 100644 (file)
 
 typedef enum {
     TypeableStore,
-    GHCConcSignalHandlerStore,
-    GHCConcPendingEventsStore,
-    GHCConcPendingDelaysStore,
-    GHCConcIOManagerThreadStore,
-    GHCConcProddingStore,
+    GHCConcSignalSignalHandlerStore,
+    GHCConcWindowsPendingDelaysStore,
+    GHCConcWindowsIOManagerThreadStore,
+    GHCConcWindowsProddingStore,
+    SystemEventThreadEventManagerStore,
+    SystemEventThreadIOManagerThreadStore,
     MaxStoreKey
 } StoreKey;
 
@@ -87,31 +88,37 @@ getOrSetTypeableStore(StgStablePtr ptr)
 }
 
 StgStablePtr
-getOrSetGHCConcSignalHandlerStore(StgStablePtr ptr)
+getOrSetGHCConcSignalSignalHandlerStore(StgStablePtr ptr)
 {
-    return getOrSetKey(GHCConcSignalHandlerStore,ptr);
+    return getOrSetKey(GHCConcSignalSignalHandlerStore,ptr);
 }
 
 StgStablePtr
-getOrSetGHCConcPendingEventsStore(StgStablePtr ptr)
+getOrSetGHCConcWindowsPendingDelaysStore(StgStablePtr ptr)
 {
-    return getOrSetKey(GHCConcPendingEventsStore,ptr);
+    return getOrSetKey(GHCConcWindowsPendingDelaysStore,ptr);
 }
 
 StgStablePtr
-getOrSetGHCConcPendingDelaysStore(StgStablePtr ptr)
+getOrSetGHCConcWindowsIOManagerThreadStore(StgStablePtr ptr)
 {
-    return getOrSetKey(GHCConcPendingDelaysStore,ptr);
+    return getOrSetKey(GHCConcWindowsIOManagerThreadStore,ptr);
 }
 
 StgStablePtr
-getOrSetGHCConcIOManagerThreadStore(StgStablePtr ptr)
+getOrSetGHCConcWindowsProddingStore(StgStablePtr ptr)
 {
-    return getOrSetKey(GHCConcIOManagerThreadStore,ptr);
+    return getOrSetKey(GHCConcWindowsProddingStore,ptr);
 }
 
 StgStablePtr
-getOrSetGHCConcProddingStore(StgStablePtr ptr)
+getOrSetSystemEventThreadEventManagerStore(StgStablePtr ptr)
 {
-    return getOrSetKey(GHCConcProddingStore,ptr);
+    return getOrSetKey(SystemEventThreadEventManagerStore,ptr);
+}
+
+StgStablePtr
+getOrSetSystemEventThreadIOManagerThreadStore(StgStablePtr ptr)
+{
+    return getOrSetKey(SystemEventThreadIOManagerThreadStore,ptr);
 }
index 67e5b56..8f0761d 100644 (file)
@@ -519,9 +519,9 @@ typedef struct _RtsSymbolVal {
 
 #if !defined(mingw32_HOST_OS)
 #define RTS_USER_SIGNALS_SYMBOLS \
-   SymI_HasProto(setIOManagerPipe) \
+   SymI_HasProto(setIOManagerControlFd) \
+   SymI_HasProto(setIOManagerWakeupFd) \
    SymI_HasProto(ioManagerWakeup) \
-   SymI_HasProto(ioManagerSync) \
    SymI_HasProto(blockUserSignals) \
    SymI_HasProto(unblockUserSignals)
 #else
@@ -770,11 +770,12 @@ typedef struct _RtsSymbolVal {
       SymI_HasProto(forkOS_createThread)               \
       SymI_HasProto(freeHaskellFunctionPtr)            \
       SymI_HasProto(getOrSetTypeableStore)             \
-      SymI_HasProto(getOrSetGHCConcSignalHandlerStore)         \
-      SymI_HasProto(getOrSetGHCConcPendingEventsStore)         \
-      SymI_HasProto(getOrSetGHCConcPendingDelaysStore)         \
-      SymI_HasProto(getOrSetGHCConcIOManagerThreadStore)       \
-      SymI_HasProto(getOrSetGHCConcProddingStore)              \
+      SymI_HasProto(getOrSetGHCConcSignalSignalHandlerStore)           \
+      SymI_HasProto(getOrSetGHCConcWindowsPendingDelaysStore)          \
+      SymI_HasProto(getOrSetGHCConcWindowsIOManagerThreadStore)        \
+      SymI_HasProto(getOrSetGHCConcWindowsProddingStore)               \
+      SymI_HasProto(getOrSetSystemEventThreadEventManagerStore)                \
+      SymI_HasProto(getOrSetSystemEventThreadIOManagerThreadStore)             \
       SymI_HasProto(genSymZh)                          \
       SymI_HasProto(genericRaise)                      \
       SymI_HasProto(getProgArgv)                       \
@@ -4877,4 +4878,3 @@ static int machoGetMisalignment( FILE * f )
 #endif
 
 #endif
-
index ba7cb14..33a9148 100644 (file)
@@ -43,9 +43,9 @@ PRELUDE_CLOSURE(base_GHCziIOziException_blockedIndefinitelyOnSTM_closure);
 PRELUDE_CLOSURE(base_ControlziExceptionziBase_nonTermination_closure);
 PRELUDE_CLOSURE(base_ControlziExceptionziBase_nestedAtomically_closure);
 
-PRELUDE_CLOSURE(base_GHCziConc_runSparks_closure);
-PRELUDE_CLOSURE(base_GHCziConc_ensureIOManagerIsRunning_closure);
-PRELUDE_CLOSURE(base_GHCziConc_runHandlers_closure);
+PRELUDE_CLOSURE(base_GHCziConcziSync_runSparks_closure);
+PRELUDE_CLOSURE(base_GHCziConcziIO_ensureIOManagerIsRunning_closure);
+PRELUDE_CLOSURE(base_GHCziConcziSignal_runHandlers_closure);
 
 PRELUDE_INFO(ghczmprim_GHCziTypes_Czh_static_info);
 PRELUDE_INFO(ghczmprim_GHCziTypes_Izh_static_info);
@@ -88,9 +88,9 @@ PRELUDE_INFO(base_GHCziStable_StablePtr_con_info);
 #define runFinalizerBatch_closure DLL_IMPORT_DATA_REF(base_GHCziWeak_runFinalizzerBatch_closure)
 #define mainIO_closure            (&ZCMain_main_closure)
 
-#define runSparks_closure         DLL_IMPORT_DATA_REF(base_GHCziConc_runSparks_closure)
-#define ensureIOManagerIsRunning_closure DLL_IMPORT_DATA_REF(base_GHCziConc_ensureIOManagerIsRunning_closure)
-#define runHandlers_closure       DLL_IMPORT_DATA_REF(base_GHCziConc_runHandlers_closure)
+#define runSparks_closure         DLL_IMPORT_DATA_REF(base_GHCziConcziSync_runSparks_closure)
+#define ensureIOManagerIsRunning_closure DLL_IMPORT_DATA_REF(base_GHCziConcziIO_ensureIOManagerIsRunning_closure)
+#define runHandlers_closure       DLL_IMPORT_DATA_REF(base_GHCziConcziSignal_runHandlers_closure)
 
 #define stackOverflow_closure     DLL_IMPORT_DATA_REF(base_GHCziIOziException_stackOverflow_closure)
 #define heapOverflow_closure      DLL_IMPORT_DATA_REF(base_GHCziIOziException_heapOverflow_closure)
index 2c9d7b4..ab5a723 100644 (file)
@@ -95,9 +95,9 @@ ld-options:
          , "-u", "_base_GHCziWeak_runFinalizzerBatch_closure"
          , "-u", "_base_GHCziTopHandler_runIO_closure"
          , "-u", "_base_GHCziTopHandler_runNonIO_closure"
-        , "-u", "_base_GHCziConc_ensureIOManagerIsRunning_closure"
-        , "-u", "_base_GHCziConc_runSparks_closure"
-        , "-u", "_base_GHCziConc_runHandlers_closure"
+        , "-u", "_base_GHCziConcziIO_ensureIOManagerIsRunning_closure"
+        , "-u", "_base_GHCziConcziSync_runSparks_closure"
+        , "-u", "_base_GHCziConcziSignal_runHandlers_closure"
 #else
            "-u", "ghczmprim_GHCziTypes_Izh_static_info"
          , "-u", "ghczmprim_GHCziTypes_Czh_static_info"
@@ -133,9 +133,9 @@ ld-options:
          , "-u", "base_GHCziWeak_runFinalizzerBatch_closure"
          , "-u", "base_GHCziTopHandler_runIO_closure"
          , "-u", "base_GHCziTopHandler_runNonIO_closure"
-        , "-u", "base_GHCziConc_ensureIOManagerIsRunning_closure"
-        , "-u", "base_GHCziConc_runSparks_closure"
-        , "-u", "base_GHCziConc_runHandlers_closure"
+        , "-u", "base_GHCziConcziIO_ensureIOManagerIsRunning_closure"
+        , "-u", "base_GHCziConcziSync_runSparks_closure"
+        , "-u", "base_GHCziConcziSignal_runHandlers_closure"
 #endif
 
 /*  Pick up static libraries in preference over dynamic if in earlier search
index 4bb1255..b045289 100644 (file)
 # include <errno.h>
 #endif
 
+#ifdef HAVE_EVENTFD_H
+# include <sys/eventfd.h>
+#endif
+
 #include <stdlib.h>
 #include <string.h>
 
@@ -82,41 +86,43 @@ more_handlers(int sig)
 }
 
 // Here's the pipe into which we will send our signals
-static int io_manager_pipe = -1;
+static int io_manager_wakeup_fd = -1;
+static int io_manager_control_fd = -1;
 
 #define IO_MANAGER_WAKEUP 0xff
 #define IO_MANAGER_DIE    0xfe
 #define IO_MANAGER_SYNC   0xfd
 
 void
-setIOManagerPipe (int fd)
+setIOManagerWakeupFd (int fd)
 {
     // only called when THREADED_RTS, but unconditionally
-    // compiled here because GHC.Conc depends on it.
-    io_manager_pipe = fd;
+    // compiled here because System.Event.Control depends on it.
+    io_manager_wakeup_fd = fd;
 }
 
 void
-ioManagerWakeup (void)
+setIOManagerControlFd (int fd)
 {
-    int r;
-    // Wake up the IO Manager thread by sending a byte down its pipe
-    if (io_manager_pipe >= 0) {
-       StgWord8 byte = (StgWord8)IO_MANAGER_WAKEUP;
-       r = write(io_manager_pipe, &byte, 1);
-        if (r == -1) { sysErrorBelch("ioManagerWakeup: write"); }
-    }
+    // only called when THREADED_RTS, but unconditionally
+    // compiled here because System.Event.Control depends on it.
+    io_manager_control_fd = fd;
 }
 
 void
-ioManagerSync (void)
+ioManagerWakeup (void)
 {
     int r;
     // Wake up the IO Manager thread by sending a byte down its pipe
-    if (io_manager_pipe >= 0) {
-       StgWord8 byte = (StgWord8)IO_MANAGER_SYNC;
-       r = write(io_manager_pipe, &byte, 1);
-        if (r == -1) { sysErrorBelch("ioManagerSync: write"); }
+    if (io_manager_wakeup_fd >= 0) {
+#if defined(HAVE_EVENTFD)
+       StgWord64 n = (StgWord64)IO_MANAGER_WAKEUP;
+       r = write(io_manager_wakeup_fd, (char *) &n, 8);
+#else
+       StgWord8 byte = (StgWord8)IO_MANAGER_WAKEUP;
+       r = write(io_manager_wakeup_fd, &byte, 1);
+#endif
+        if (r == -1) { sysErrorBelch("ioManagerWakeup: write"); }
     }
 }
 
@@ -126,19 +132,20 @@ ioManagerDie (void)
 {
     int r;
     // Ask the IO Manager thread to exit
-    if (io_manager_pipe >= 0) {
+    if (io_manager_control_fd >= 0) {
        StgWord8 byte = (StgWord8)IO_MANAGER_DIE;
-       r = write(io_manager_pipe, &byte, 1);
+       r = write(io_manager_control_fd, &byte, 1);
         if (r == -1) { sysErrorBelch("ioManagerDie: write"); }
-        close(io_manager_pipe);
-        io_manager_pipe = -1;
+        io_manager_control_fd = -1;
+        io_manager_wakeup_fd = -1;
     }
 }
 
 Capability *
 ioManagerStartCap (Capability *cap)
 {
-    return rts_evalIO(cap,&base_GHCziConc_ensureIOManagerIsRunning_closure,NULL);
+    return rts_evalIO(
+        cap,&base_GHCziConcziIO_ensureIOManagerIsRunning_closure,NULL);
 }
 
 void
@@ -146,7 +153,7 @@ ioManagerStart (void)
 {
     // Make sure the IO manager thread is running
     Capability *cap;
-    if (io_manager_pipe < 0) {
+    if (io_manager_control_fd < 0 || io_manager_wakeup_fd < 0) {
        cap = rts_lock();
        cap = ioManagerStartCap(cap);
        rts_unlock(cap);
@@ -177,7 +184,7 @@ generic_handler(int sig USED_IF_THREADS,
 {
 #if defined(THREADED_RTS)
 
-    if (io_manager_pipe != -1)
+    if (io_manager_control_fd != -1)
     {
         StgWord8 buf[sizeof(siginfo_t) + 1];
         int r;
@@ -191,7 +198,7 @@ generic_handler(int sig USED_IF_THREADS,
            memcpy(buf+1, info, sizeof(siginfo_t));
        }
 
-       r = write(io_manager_pipe, buf, sizeof(siginfo_t)+1);
+       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);
@@ -258,7 +265,7 @@ initUserSignals(void)
 {
     sigemptyset(&userSignals);
 #ifndef THREADED_RTS
-    getStablePtr((StgPtr)&base_GHCziConc_runHandlers_closure); 
+    getStablePtr((StgPtr)&base_GHCziConcziSignal_runHandlers_closure);
     // needed to keep runHandler alive
 #endif
 }
@@ -412,7 +419,7 @@ startSignalHandlers(Capability *cap)
                       RtsFlags.GcFlags.initialStkSize, 
                        rts_apply(cap,
                                  rts_apply(cap,
-                                           &base_GHCziConc_runHandlers_closure,
+                                           &base_GHCziConcziSignal_runHandlers_closure,
                                            rts_mkPtr(cap, info)),
                                  rts_mkInt(cap, info->si_signo))));
   }
index 054f568..f48b203 100644 (file)
@@ -153,9 +153,9 @@ ioManagerStart (void)
     if (io_manager_event == INVALID_HANDLE_VALUE) {\r
        cap = rts_lock();\r
 #if defined(mingw32_HOST_OS) && defined(__PIC__)\r
-       rts_evalIO(cap,_imp__base_GHCziConc_ensureIOManagerIsRunning_closure,NULL);\r
+       rts_evalIO(cap,_imp__base_GHCziConcziIO_ensureIOManagerIsRunning_closure,NULL);\r
 #else\r
-       rts_evalIO(cap,&base_GHCziConc_ensureIOManagerIsRunning_closure,NULL);\r
+       rts_evalIO(cap,&base_GHCziConcziIO_ensureIOManagerIsRunning_closure,NULL);\r
 #endif\r
        rts_unlock(cap);\r
     }\r
index 8f5f54e..b5c8a37 100644 (file)
@@ -27,8 +27,8 @@ EXPORTS
        base_GHCziPtr_Ptr_con_info
        base_GHCziPtr_FunPtr_con_info
 
-       base_GHCziConc_ensureIOManagerIsRunning_closure
-       base_GHCziConc_runSparks_closure
+       base_GHCziConcziIO_ensureIOManagerIsRunning_closure
+       base_GHCziConcziSync_runSparks_closure
 
        base_GHCziWeak_runFinalizzerBatch_closure
        base_GHCziPack_unpackCString_closure