diff --git a/rts/Capability.c b/rts/Capability.c index c8e15c178d565e634591db8a86d5d4e2cd1729e1..a9fe393a08db207bab3a60b1c14dda5ac1ad7fd2 100644 --- a/rts/Capability.c +++ b/rts/Capability.c @@ -281,7 +281,7 @@ initCapability (Capability *cap, uint32_t i) #endif cap->total_allocated = 0; - initCapabilityIOManager(&cap->iomgr); + initCapabilityIOManager(cap); /* initialises cap->iomgr */ cap->f.stgEagerBlackholeInfo = (W_)&__stg_EAGER_BLACKHOLE_info; cap->f.stgGCEnter1 = (StgFunPtr)__stg_gc_enter_1; diff --git a/rts/IOManager.c b/rts/IOManager.c index e6db47fa50fe7fe3d421716a806daa2cb4367e0d..e0e4ef04ac2e207446e00926b0a18fe7c6f40182 100644 --- a/rts/IOManager.c +++ b/rts/IOManager.c @@ -174,8 +174,11 @@ parseIOManagerFlag(const char *iomgrstr, IO_MANAGER_FLAG *flag) * * This fills in the iomgr_type and rts_IOManagerIsWin32Native globals. * Must be called before the I/O manager is started. + * + * Called early in the RTS initialisation, after the RTS flags have been + * processed. */ -static void selectIOManager(void) +void selectIOManager(void) { switch (RtsFlags.MiscFlags.ioManager) { case IO_MNGR_FLAG_AUTO: @@ -242,9 +245,13 @@ static void selectIOManager(void) /* Allocate and initialise the per-capability CapIOManager that lives in each - * Capability. Called early in the RTS initialisation. + * Capability. Called from initCapability(), which is done in the RTS startup + * in initCapabilities(), and later at runtime via setNumCapabilities(). + * + * Note that during RTS startup this is called _before_ the storage manager + * is initialised, so this is not allowed to allocate on the GC heap. */ -void initCapabilityIOManager(CapIOManager **piomgr) +void initCapabilityIOManager(Capability *cap) { CapIOManager *iomgr = (CapIOManager *) stgMallocBytes(sizeof(CapIOManager), @@ -275,20 +282,18 @@ void initCapabilityIOManager(CapIOManager **piomgr) break; } - *piomgr = iomgr; + cap->iomgr = iomgr; } /* Called late in the RTS initialisation */ -void -initIOManager(void) +void initIOManager(void) { - selectIOManager(); switch (iomgr_type) { - /* The IO_MANAGER_SELECT needs no initialisation */ + /* The IO_MANAGER_SELECT needs no global initialisation */ #if defined(IOMGR_ENABLED_MIO_POSIX) case IO_MANAGER_MIO_POSIX: diff --git a/rts/IOManager.h b/rts/IOManager.h index 24218e9315d061197cd0ee8005dad2cba5e3e8eb..b54dbd0974d1b8df15841a6c5909657b488744e3 100644 --- a/rts/IOManager.h +++ b/rts/IOManager.h @@ -214,11 +214,19 @@ typedef struct { } CapIOManager; +/* Init hook: called from hs_init_ghc, early in the startup after the RTS flags + * have been processed. + * + * Based on the I/O manager RTS flag, select an I/O manager to use. + */ +void selectIOManager(void); + + /* Allocate and initialise the per-capability CapIOManager that lives in each - * Capability. It is called from initCapability, via initScheduler, - * via hs_init_ghc. + * Capability. Called from initCapability(), which is done in the RTS startup + * in initCapabilities(), and later at runtime via setNumCapabilities(). */ -void initCapabilityIOManager(CapIOManager **iomgr); +void initCapabilityIOManager(Capability *cap); /* Init hook: called from hs_init_ghc, very late in the startup after almost diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c index cfbd0421f5d4f0c4c6948495310d417cf9e3ed0f..70e926b44623fe9a65fd6df683e7b8cd93736059 100644 --- a/rts/RtsStartup.c +++ b/rts/RtsStartup.c @@ -331,6 +331,9 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config) #endif /* DEBUG */ } + /* Based on the RTS flags, decide which I/O manager to use. */ + selectIOManager(); + /* Initialize console Codepage. */ #if defined(mingw32_HOST_OS) if (is_io_mng_native_p())