#include "RtsTypeable.h"
#include "Stable.h"
#include "Hpc.h"
+#include "FileLock.h"
#if defined(RTS_GTK_FRONTPANEL)
#include "FrontPanel.h"
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
#if USE_PAPI
#include "Papi.h"
return;
}
-#if defined(DEBUG)
- /* Start off by initialising the allocator debugging so we can
- * use it anywhere */
- initAllocator();
-#endif
+ /* Initialise the stats department, phase 0 */
+ initStats0();
/* Next we do is grab the start time...just in case we're
* collecting timing statistics.
*/
stat_startInit();
+#if defined(DEBUG)
+ /* Start off by initialising the allocator debugging so we can
+ * use it anywhere */
+ initAllocator();
+#endif
+
#ifdef PAR
/*
* The parallel system needs to be initialised and synchronised before
argv++; argc--;
#endif
- /* Initialise the performance tracking library */
-#ifdef USE_PAPI
- {
- int ver;
- if ((ver = PAPI_library_init(PAPI_VER_CURRENT)) != PAPI_VER_CURRENT) {
- if (ver > 0) {
- errorBelch("PAPI_library_init: wrong version: %x", ver);
- stg_exit(EXIT_FAILURE);
- } else {
- sysErrorBelch("PAPI_library_init");
- stg_exit(EXIT_FAILURE);
- }
- }
- }
-#ifdef THREADED_RTS
- {
- int err;
- if ((err = PAPI_thread_init(osThreadId)) < 0) {
- barf("PAPI_thread_init: %d",err);
- }
- }
-#endif
-#endif
-
/* Set the RTS flags to default values. */
initRtsFlagsDefaults();
setProgArgv(*argc,*argv);
}
+ /* Initialise the stats department, phase 1 */
+ initStats1();
+
+#ifdef USE_PAPI
+ papi_init();
+#endif
+
/* initTracing must be after setupRtsFlags() */
initTracing();
/* initialise the stable pointer table */
initStablePtrTable();
+ /* Add some GC roots for things in the base package that the RTS
+ * knows about. We don't know whether these turn out to be CAFs
+ * or refer to CAFs, but we have to assume that they might.
+ */
+ getStablePtr((StgPtr)base_GHCziTopHandler_runIO_closure);
+ getStablePtr((StgPtr)base_GHCziTopHandler_runNonIO_closure);
+ getStablePtr((StgPtr)stackOverflow_closure);
+ getStablePtr((StgPtr)heapOverflow_closure);
+ getStablePtr((StgPtr)runFinalizerBatch_closure);
+ getStablePtr((StgPtr)unpackCString_closure);
+ getStablePtr((StgPtr)blockedOnDeadMVar_closure);
+ getStablePtr((StgPtr)nonTermination_closure);
+ getStablePtr((StgPtr)blockedIndefinitely_closure);
+
/* initialise the shared Typeable store */
initTypeableStore();
+ /* initialise file locking, if necessary */
+#if !defined(mingw32_HOST_OS)
+ initFileLocking();
+#endif
+
#if defined(DEBUG)
/* initialise thread label table (tso->char*) */
initThreadLabelTable();
initProfiling1();
/* start the virtual timer 'subsystem'. */
+ initTimer();
startTimer();
- /* Initialise the stats department */
- initStats();
-
#if defined(RTS_USER_SIGNALS)
if (RtsFlags.MiscFlags.install_signal_handlers) {
/* Initialise the user signal handler set */
x86_init_fpu();
#endif
-#if defined(THREADED_RTS)
- ioManagerStart();
-#endif
-
/* Record initialization times */
stat_endInit();
}
{
bdescr *bd;
nat init_sp;
- Capability *cap = &MainCapability;
+ Capability *cap;
+
+ cap = rts_lock();
if (hs_init_count <= 0) {
barf("hs_add_root() must be called after hs_init()");
// This must be done after module initialisation.
// ToDo: make this work in the presence of multiple hs_add_root()s.
initProfiling2();
+
+ rts_unlock(cap);
+
+ // ditto.
+#if defined(THREADED_RTS)
+ ioManagerStart();
+#endif
}
/* ----------------------------------------------------------------------------
/* start timing the shutdown */
stat_startExit();
+ OnExitHook();
+
#if defined(RTS_USER_SIGNALS)
if (RtsFlags.MiscFlags.install_signal_handlers) {
freeSignalHandlers();
/* stop the ticker */
stopTimer();
+ exitTimer();
/* reset the standard file descriptors to blocking mode */
resetNonBlockingFd(0);
PAR_TICKY_PAR_END();
#endif
+ // uninstall signal handlers
+ resetDefaultHandlers();
+
/* stop timing the shutdown, we're about to print stats */
stat_endExit();
/* free shared Typeable store */
exitTypeableStore();
+ /* free file locking tables, if necessary */
+#if !defined(mingw32_HOST_OS)
+ freeFileLocking();
+#endif
+
/* free the stable pointer table */
exitStablePtrTable();
reportCCSProfiling();
#endif
- freeProfiling1();
-
endProfiling();
+ freeProfiling1();
#ifdef PROFILING
// Originally, this was in report_ccs_profiling(). Now, retainer
// profiling might tack some extra stuff on to the end of this file
// during endProfiling().
- fclose(prof_file);
+ if (prof_file != NULL) fclose(prof_file);
#endif
#if defined(TICKY_TICKY)
void
shutdownHaskellAndExit(int n)
{
- if (hs_init_count == 1) {
- OnExitHook();
- hs_exit_(rtsFalse);
- // we're about to exit(), no need to wait for foreign calls to return.
+ // we're about to exit(), no need to wait for foreign calls to return.
+ hs_exit_(rtsFalse);
+
+ if (hs_init_count == 0) {
#if defined(PAR)
/* really exit (stg_exit() would call shutdownParallelSystem() again) */
exit(n);
}
}
+#ifndef mingw32_HOST_OS
+void
+shutdownHaskellAndSignal(int sig)
+{
+ hs_exit_(rtsFalse);
+ kill(getpid(),sig);
+}
+#endif
+
/*
* called from STG-land to exit the program
*/