Commit 40114073 authored by tibbe's avatar tibbe

Integrate new I/O manager, with signal support

parent 0cbdc7b1
......@@ -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
......
......@@ -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 */
......@@ -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
......
......@@ -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);
}
......@@ -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
......@@ -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)
......
......@@ -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
......
......@@ -36,6 +36,10 @@
# 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))));
}
......
......@@ -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);
}
......
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment