Commit 2d5e052d authored by Simon Marlow's avatar Simon Marlow
Browse files

Second attempt to fix #1185 (forkProcess and -threaded)

Patch 1/2: second part of the patch is to libraries/base

This time without dynamic linker hacks, instead I've expanded the
existing rts/Globals.c to cache more CAFs, specifically those in
GHC.Conc.  We were already using this trick for signal handlers, I
should have realised before.

It's still quite unsavoury, but we can do away with rts/Globals.c in
the future when we switch to a dynamically-linked GHCi.
parent cd0e2c0c
......@@ -18,6 +18,10 @@
#define RTS_GLOBALS_H
StgStablePtr getOrSetTypeableStore(StgStablePtr value);
StgStablePtr getOrSetSignalHandlerStore(StgStablePtr value);
StgStablePtr getOrSetGHCConcSignalHandlerStore(StgStablePtr value);
StgStablePtr getOrSetGHCConcPendingEventsStore(StgStablePtr ptr);
StgStablePtr getOrSetGHCConcPendingDelaysStore(StgStablePtr ptr);
StgStablePtr getOrSetGHCConcIOManagerThreadStore(StgStablePtr ptr);
StgStablePtr getOrSetGHCConcProddingStore(StgStablePtr ptr);
#endif /* RTS_GLOBALS_H */
......@@ -27,6 +27,7 @@ void sendIOManagerEvent (HsWord32 event);
#else
void setIOManagerPipe (int fd);
void ioManagerSync (void);
#endif
......@@ -35,8 +36,8 @@ void setIOManagerPipe (int fd);
// Posix implementation in posix/Signals.c
// Win32 implementation in win32/ThrIOManager.c
//
#if defined(THREADED_RTS)
void ioManagerWakeup (void);
#if defined(THREADED_RTS)
void ioManagerDie (void);
void ioManagerStart (void);
#endif
......
......@@ -7,6 +7,9 @@
* even when multiple versions of the library are loaded. e.g. see
* Data.Typeable and GHC.Conc.
*
* If/when we switch to a dynamically-linked GHCi, this can all go
* away, because there would be just one copy of each library.
*
* ---------------------------------------------------------------------------*/
#include "PosixSource.h"
......@@ -15,18 +18,29 @@
#include "Globals.h"
#include "Stable.h"
static StgStablePtr typeableStore = 0;
static StgStablePtr signalHandlerStore = 0;
typedef enum {
TypeableStore,
GHCConcSignalHandlerStore,
GHCConcPendingEventsStore,
GHCConcPendingDelaysStore,
GHCConcIOManagerThreadStore,
GHCConcProddingStore,
MaxStoreKey
} StoreKey;
#ifdef THREADED_RTS
Mutex globalStoreLock;
#endif
StgStablePtr store[MaxStoreKey];
void
initGlobalStore(void)
{
typeableStore = 0;
signalHandlerStore = 0;
nat i;
for (i=0; i < MaxStoreKey; i++) {
store[i] = 0;
}
#ifdef THREADED_RTS
initMutex(&globalStoreLock);
#endif
......@@ -35,30 +49,28 @@ initGlobalStore(void)
void
exitGlobalStore(void)
{
nat i;
#ifdef THREADED_RTS
closeMutex(&globalStoreLock);
#endif
if(typeableStore!=0) {
freeStablePtr((StgStablePtr)typeableStore);
typeableStore=0;
for (i=0; i < MaxStoreKey; i++) {
if (store[i] != 0) {
freeStablePtr(store[i]);
store[i] = 0;
}
if(signalHandlerStore!=0) {
freeStablePtr((StgStablePtr)signalHandlerStore);
signalHandlerStore=0;
}
}
StgStablePtr
getOrSetTypeableStore(StgStablePtr ptr)
static StgStablePtr getOrSetKey(StoreKey key, StgStablePtr ptr)
{
StgStablePtr ret = typeableStore;
StgStablePtr ret = store[key];
if(ret==0) {
#ifdef THREADED_RTS
ACQUIRE_LOCK(&globalStoreLock);
ret=typeableStore;
ret = store[key];
if(ret==0) {
#endif
typeableStore = ret = ptr;
store[key] = ret = ptr;
#ifdef THREADED_RTS
}
RELEASE_LOCK(&globalStoreLock);
......@@ -67,21 +79,39 @@ getOrSetTypeableStore(StgStablePtr ptr)
return ret;
}
StgStablePtr
getOrSetSignalHandlerStore(StgStablePtr ptr)
getOrSetTypeableStore(StgStablePtr ptr)
{
StgStablePtr ret = signalHandlerStore;
if(ret==0) {
#ifdef THREADED_RTS
ACQUIRE_LOCK(&globalStoreLock);
ret=signalHandlerStore;
if(ret==0) {
#endif
signalHandlerStore = ret = ptr;
#ifdef THREADED_RTS
}
RELEASE_LOCK(&globalStoreLock);
#endif
}
return ret;
return getOrSetKey(TypeableStore,ptr);
}
StgStablePtr
getOrSetGHCConcSignalHandlerStore(StgStablePtr ptr)
{
return getOrSetKey(GHCConcSignalHandlerStore,ptr);
}
StgStablePtr
getOrSetGHCConcPendingEventsStore(StgStablePtr ptr)
{
return getOrSetKey(GHCConcPendingEventsStore,ptr);
}
StgStablePtr
getOrSetGHCConcPendingDelaysStore(StgStablePtr ptr)
{
return getOrSetKey(GHCConcPendingDelaysStore,ptr);
}
StgStablePtr
getOrSetGHCConcIOManagerThreadStore(StgStablePtr ptr)
{
return getOrSetKey(GHCConcIOManagerThreadStore,ptr);
}
StgStablePtr
getOrSetGHCConcProddingStore(StgStablePtr ptr)
{
return getOrSetKey(GHCConcProddingStore,ptr);
}
......@@ -505,10 +505,13 @@ typedef struct _RtsSymbolVal {
#if !defined(mingw32_HOST_OS)
#define RTS_USER_SIGNALS_SYMBOLS \
SymI_HasProto(setIOManagerPipe) \
SymI_HasProto(ioManagerWakeup) \
SymI_HasProto(ioManagerSync) \
SymI_HasProto(blockUserSignals) \
SymI_HasProto(unblockUserSignals)
#else
#define RTS_USER_SIGNALS_SYMBOLS \
SymI_HasProto(ioManagerWakeup) \
SymI_HasProto(sendIOManagerEvent) \
SymI_HasProto(readIOManagerEvent) \
SymI_HasProto(getIOManagerEvent) \
......@@ -736,7 +739,11 @@ typedef struct _RtsSymbolVal {
SymI_HasProto(forkOS_createThread) \
SymI_HasProto(freeHaskellFunctionPtr) \
SymI_HasProto(getOrSetTypeableStore) \
SymI_HasProto(getOrSetSignalHandlerStore) \
SymI_HasProto(getOrSetGHCConcSignalHandlerStore) \
SymI_HasProto(getOrSetGHCConcPendingEventsStore) \
SymI_HasProto(getOrSetGHCConcPendingDelaysStore) \
SymI_HasProto(getOrSetGHCConcIOManagerThreadStore) \
SymI_HasProto(getOrSetGHCConcProddingStore) \
SymI_HasProto(genSymZh) \
SymI_HasProto(genericRaise) \
SymI_HasProto(getProgArgv) \
......
......@@ -86,18 +86,16 @@ static int io_manager_pipe = -1;
#define IO_MANAGER_WAKEUP 0xff
#define IO_MANAGER_DIE 0xfe
#define IO_MANAGER_SYNC 0xfd
void
setIOManagerPipe (int fd)
{
// only called when THREADED_RTS, but unconditionally
// compiled here because GHC.Conc depends on it.
if (io_manager_pipe < 0) {
io_manager_pipe = fd;
}
}
#if defined(THREADED_RTS)
void
ioManagerWakeup (void)
{
......@@ -110,6 +108,19 @@ ioManagerWakeup (void)
}
}
void
ioManagerSync (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 defined(THREADED_RTS)
void
ioManagerDie (void)
{
......
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