diff options
author | Simon Marlow <simonmar@microsoft.com> | 2006-05-24 12:28:39 +0000 |
---|---|---|
committer | Simon Marlow <simonmar@microsoft.com> | 2006-05-24 12:28:39 +0000 |
commit | 7a1f8fbdbab99465793c50bd9fb376c950e7e9d7 (patch) | |
tree | 04e40cc95c37d452ed26ca9909b1ff97abe8aeac /rts/posix | |
parent | 3065ea2499deee8d4152eaf0804cc92c7217a2ba (diff) | |
download | haskell-7a1f8fbdbab99465793c50bd9fb376c950e7e9d7.tar.gz |
Better control of the IO manager thread; improvements to deadlock checking
In the threaded RTS on *nix platforms:
- we now start the IO manager thread eagerly at startup time
(previously was started on demand).
- we now ask the IO manager thread to stop at shutdown
- In Timer.c:handle_tick, if it looks like we might be in a
deadlock, instead of calling prodOneCapability() which was known to be
wrong, we now send a byte down the IO manager's pipe to wake it up.
This also avoids a case of double-acquisition of a mutex, which
happened if prodOneCapability() was called while the current thread
was holding a mutex.
Diffstat (limited to 'rts/posix')
-rw-r--r-- | rts/posix/Signals.c | 38 | ||||
-rw-r--r-- | rts/posix/Signals.h | 6 |
2 files changed, 43 insertions, 1 deletions
diff --git a/rts/posix/Signals.c b/rts/posix/Signals.c index 5f5f77fd39..2303d9f89b 100644 --- a/rts/posix/Signals.c +++ b/rts/posix/Signals.c @@ -16,6 +16,7 @@ #include "posix/Signals.h" #include "RtsUtils.h" #include "RtsFlags.h" +#include "Prelude.h" #ifdef alpha_HOST_ARCH # if defined(linux_HOST_OS) @@ -107,6 +108,9 @@ more_handlers(I_ sig) // Here's the pipe into which we will send our signals static int io_manager_pipe = -1; +#define IO_MANAGER_WAKEUP 0xff +#define IO_MANAGER_DIE 0xfe + void setIOManagerPipe (int fd) { @@ -115,6 +119,40 @@ setIOManagerPipe (int fd) io_manager_pipe = fd; } +#if defined(THREADED_RTS) +void +ioManagerWakeup (void) +{ + // Wake up the IO Manager thread by sending a byte down its pipe + if (io_manager_pipe >= 0) { + StgWord8 byte = (StgWord8)IO_MANAGER_WAKEUP; + write(io_manager_pipe, &byte, 1); + } +} + +void +ioManagerDie (void) +{ + // Ask the IO Manager thread to exit + if (io_manager_pipe >= 0) { + StgWord8 byte = (StgWord8)IO_MANAGER_DIE; + write(io_manager_pipe, &byte, 1); + } +} + +void +ioManagerStart (void) +{ + // Make sure the IO manager thread is running + Capability *cap; + if (io_manager_pipe < 0) { + cap = rts_lock(); + rts_evalIO(cap,&GHCziConc_ensureIOManagerIsRunning_closure,NULL); + rts_unlock(cap); + } +} +#endif + #if !defined(THREADED_RTS) #define N_PENDING_HANDLERS 16 diff --git a/rts/posix/Signals.h b/rts/posix/Signals.h index 39477f8c6a..b005abb5b5 100644 --- a/rts/posix/Signals.h +++ b/rts/posix/Signals.h @@ -12,12 +12,16 @@ extern rtsBool anyUserHandlers(void); #if !defined(THREADED_RTS) - extern StgPtr pending_handler_buf[]; extern StgPtr *next_pending_handler; #define signals_pending() (next_pending_handler != pending_handler_buf) void startSignalHandlers(Capability *cap); +#endif +#if defined(THREADED_RTS) +void ioManagerWakeup (void); +void ioManagerDie (void); +void ioManagerStart (void); #endif extern StgInt *signal_handlers; |