From 401140734891ca804c336122581743251d61b3a6 Mon Sep 17 00:00:00 2001 From: Johan Tibell Date: Sat, 24 Jul 2010 10:23:55 +0000 Subject: [PATCH] Integrate new I/O manager, with signal support --- configure.ac | 4 +++ includes/rts/Globals.h | 11 +++++---- includes/rts/IOManager.h | 4 +-- rts/Globals.c | 37 ++++++++++++++++------------ rts/Linker.c | 16 ++++++------ rts/Prelude.h | 12 ++++----- rts/package.conf.in | 12 ++++----- rts/posix/Signals.c | 61 ++++++++++++++++++++++++++-------------------- rts/win32/ThrIOManager.c | 4 +-- rts/win32/libHSbase.def | 4 +-- 10 files changed, 92 insertions(+), 73 deletions(-) diff --git a/configure.ac b/configure.ac index 33614e0..3d05a0f 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/includes/rts/Globals.h b/includes/rts/Globals.h index 75c7f69..218b7ef 100644 --- a/includes/rts/Globals.h +++ b/includes/rts/Globals.h @@ -18,10 +18,11 @@ #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 */ diff --git a/includes/rts/IOManager.h b/includes/rts/IOManager.h index 3aedda8..bf93d97 100644 --- a/includes/rts/IOManager.h +++ b/includes/rts/IOManager.h @@ -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 diff --git a/rts/Globals.c b/rts/Globals.c index 01d8a8f..7b8967f 100644 --- a/rts/Globals.c +++ b/rts/Globals.c @@ -20,11 +20,12 @@ 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); } diff --git a/rts/Linker.c b/rts/Linker.c index 67e5b56..8f0761d 100644 --- a/rts/Linker.c +++ b/rts/Linker.c @@ -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 - diff --git a/rts/Prelude.h b/rts/Prelude.h index ba7cb14..33a9148 100644 --- a/rts/Prelude.h +++ b/rts/Prelude.h @@ -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) diff --git a/rts/package.conf.in b/rts/package.conf.in index 2c9d7b4..ab5a723 100644 --- a/rts/package.conf.in +++ b/rts/package.conf.in @@ -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 diff --git a/rts/posix/Signals.c b/rts/posix/Signals.c index 4bb1255..b045289 100644 --- a/rts/posix/Signals.c +++ b/rts/posix/Signals.c @@ -36,6 +36,10 @@ # include #endif +#ifdef HAVE_EVENTFD_H +# include +#endif + #include #include @@ -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)))); } diff --git a/rts/win32/ThrIOManager.c b/rts/win32/ThrIOManager.c index 054f568..f48b203 100644 --- a/rts/win32/ThrIOManager.c +++ b/rts/win32/ThrIOManager.c @@ -153,9 +153,9 @@ ioManagerStart (void) if (io_manager_event == INVALID_HANDLE_VALUE) { cap = rts_lock(); #if defined(mingw32_HOST_OS) && defined(__PIC__) - rts_evalIO(cap,_imp__base_GHCziConc_ensureIOManagerIsRunning_closure,NULL); + rts_evalIO(cap,_imp__base_GHCziConcziIO_ensureIOManagerIsRunning_closure,NULL); #else - rts_evalIO(cap,&base_GHCziConc_ensureIOManagerIsRunning_closure,NULL); + rts_evalIO(cap,&base_GHCziConcziIO_ensureIOManagerIsRunning_closure,NULL); #endif rts_unlock(cap); } diff --git a/rts/win32/libHSbase.def b/rts/win32/libHSbase.def index 8f5f54e..b5c8a37 100644 --- a/rts/win32/libHSbase.def +++ b/rts/win32/libHSbase.def @@ -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 -- 1.7.10.4