#include "HsFFI.h"
#include "sm/Storage.h"
+#include "RtsFlags.h"
#include "RtsUtils.h"
#include "Prelude.h"
#include "Schedule.h" /* initScheduler */
#include "Profiling.h"
#include "Timer.h"
#include "Globals.h"
+void exitLinker( void ); // there is no Linker.h file to include
#if defined(RTS_GTK_FRONTPANEL)
#include "FrontPanel.h"
static int hs_init_count = 0;
/* -----------------------------------------------------------------------------
- Initialise floating point unit on x86 (currently disabled. why?)
- (see comment in ghc/compiler/nativeGen/MachInstrs.lhs).
+ Initialise floating point unit on x86 (currently disabled; See Note
+ [x86 Floating point precision] in compiler/nativeGen/X86/Instr.hs)
-------------------------------------------------------------------------- */
#define X86_INIT_FPU 0
*/
stat_startInit();
-#if defined(DEBUG)
- /* Start off by initialising the allocator debugging so we can
- * use it anywhere */
- initAllocator();
-#endif
-
/* Set the RTS flags to default values. */
initRtsFlagsDefaults();
/* Parse the flags, separating the RTS flags from the programs args */
if (argc != NULL && argv != NULL) {
setFullProgArgv(*argc,*argv);
- setupRtsFlags(argc, *argv, &rts_argc, rts_argv);
- setProgArgv(*argc,*argv);
+ setupRtsFlags(argc, *argv);
}
/* Initialise the stats department, phase 1 */
#ifdef TRACING
initTracing();
#endif
+ /* Dtrace events are always enabled
+ */
+ dtraceEventStartup();
/* initialise scheduler data structures (needs to be done before
* initStorage()).
*/
getStablePtr((StgPtr)runIO_closure);
getStablePtr((StgPtr)runNonIO_closure);
+
+ getStablePtr((StgPtr)runFinalizerBatch_closure);
+
getStablePtr((StgPtr)stackOverflow_closure);
getStablePtr((StgPtr)heapOverflow_closure);
- getStablePtr((StgPtr)runFinalizerBatch_closure);
getStablePtr((StgPtr)unpackCString_closure);
getStablePtr((StgPtr)blockedIndefinitelyOnMVar_closure);
getStablePtr((StgPtr)nonTermination_closure);
getStablePtr((StgPtr)blockedIndefinitelyOnSTM_closure);
+ getStablePtr((StgPtr)nestedAtomically_closure);
+
+ getStablePtr((StgPtr)runSparks_closure);
+ getStablePtr((StgPtr)ensureIOManagerIsRunning_closure);
+#ifndef mingw32_HOST_OS
+ getStablePtr((StgPtr)runHandlers_closure);
+#endif
/* initialise the shared Typeable store */
initGlobalStore();
x86_init_fpu();
#endif
+ startupHpc();
+
+ // This must be done after module initialisation.
+ // ToDo: make this work in the presence of multiple hs_add_root()s.
+ initProfiling2();
+
+ // ditto.
+#if defined(THREADED_RTS)
+ ioManagerStart();
+#endif
+
/* Record initialization times */
stat_endInit();
}
// Compatibility interface
void
-startupHaskell(int argc, char *argv[], void (*init_root)(void))
+startupHaskell(int argc, char *argv[], void (*init_root)(void) STG_UNUSED)
{
hs_init(&argc, &argv);
- if(init_root)
- hs_add_root(init_root);
}
/* -----------------------------------------------------------------------------
- Per-module initialisation
-
- This process traverses all the compiled modules in the program
- starting with "Main", and performing per-module initialisation for
- each one.
-
- So far, two things happen at initialisation time:
-
- - we register stable names for each foreign-exported function
- in that module. This prevents foreign-exported entities, and
- things they depend on, from being garbage collected.
-
- - we supply a unique integer to each statically declared cost
- centre and cost centre stack in the program.
-
- The code generator inserts a small function "__stginit_<module>" in each
- module and calls the registration functions in each of the modules it
- imports.
-
- The init* functions are compiled in the same way as STG code,
- i.e. without normal C call/return conventions. Hence we must use
- StgRun to call this stuff.
+ hs_add_root: backwards compatibility. (see #3252)
-------------------------------------------------------------------------- */
-/* The init functions use an explicit stack...
- */
-#define INIT_STACK_BLOCKS 4
-static StgFunPtr *init_stack = NULL;
-
void
-hs_add_root(void (*init_root)(void))
+hs_add_root(void (*init_root)(void) STG_UNUSED)
{
- bdescr *bd;
- nat init_sp;
- Capability *cap;
-
- cap = rts_lock();
-
- if (hs_init_count <= 0) {
- barf("hs_add_root() must be called after hs_init()");
- }
-
- /* The initialisation stack grows downward, with sp pointing
- to the last occupied word */
- init_sp = INIT_STACK_BLOCKS*BLOCK_SIZE_W;
- bd = allocGroup_lock(INIT_STACK_BLOCKS);
- init_stack = (StgFunPtr *)bd->start;
- init_stack[--init_sp] = (StgFunPtr)stg_init_finish;
- if (init_root != NULL) {
- init_stack[--init_sp] = (StgFunPtr)init_root;
- }
-
- cap->r.rSp = (P_)(init_stack + init_sp);
- StgRun((StgFunPtr)stg_init, &cap->r);
-
- freeGroup_lock(bd);
-
- startupHpc();
-
- // 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
+ /* nothing */
}
/* ----------------------------------------------------------------------------
OnExitHook();
+ // sanity check
+#if defined(DEBUG)
+ checkFPUStack();
+#endif
+
+ // Free the full argv storage
+ freeFullProgArgv();
+
#if defined(THREADED_RTS)
ioManagerDie();
#endif
/* stop the ticker */
stopTimer();
- exitTimer();
+ exitTimer(wait_foreign);
// set the terminal settings back to what they were
#if !defined(mingw32_HOST_OS)
/* free shared Typeable store */
exitGlobalStore();
+ /* free linker data */
+ exitLinker();
+
/* free file locking tables, if necessary */
#if !defined(mingw32_HOST_OS)
freeFileLocking();
#endif
endProfiling();
- freeProfiling1();
+ freeProfiling();
#ifdef PROFILING
// Originally, this was in report_ccs_profiling(). Now, retainer
/* free hash table storage */
exitHashTable();
- // Finally, free all our storage
- freeStorage();
-
-#if defined(DEBUG)
- /* and shut down the allocator debugging */
- shutdownAllocator();
-#endif
+ // Finally, free all our storage. However, we only free the heap
+ // memory if we have waited for foreign calls to complete;
+ // otherwise a foreign call in progress may still be referencing
+ // heap memory (e.g. by being passed a ByteArray#).
+ freeStorage(wait_foreign);
}