/* -----------------------------------------------------------------------------
- * $Id: RtsStartup.c,v 1.8 1999/03/03 19:10:37 sof Exp $
+ * $Id: RtsStartup.c,v 1.21 1999/09/22 11:53:33 sof Exp $
*
* (c) The GHC Team, 1998-1999
*
#include "StablePriv.h" /* initStablePtrTable */
#include "Schedule.h" /* initScheduler */
#include "Stats.h" /* initStats */
+#include "Signals.h"
+#include "Itimer.h"
#include "Weak.h"
#include "Ticky.h"
#if defined(PROFILING)
# include "ProfRts.h"
-#elif defined(DEBUG)
-# include "DebugProf.h"
+# include "ProfHeap.h"
#endif
#ifdef PAR
#include "LLC.h"
#endif
-#ifndef aix_TARGET_OS /* AIX gives link errors with this as a const (RO assembler section) */
-const
-#endif
- StgClosure *PrelBase_Bool_closure_tbl[] = {
-#ifndef HAVE_WIN32_DLL_SUPPORT
- &False_closure,
- &True_closure
-#else
- &dummy_ret_closure,
- &dummy_ret_closure
-#endif
-};
-
/*
* Flag Structure
*/
struct RTS_FLAGS RtsFlags;
-extern void startupHaskell(int argc, char *argv[])
+static int rts_has_started_up = 0;
+
+void
+startupHaskell(int argc, char *argv[])
{
- static int rts_has_started_up = 0;
+#ifdef ENABLE_WIN32_DLL_SUPPORT
int i;
+#endif
/* To avoid repeated initialisations of the RTS */
if (rts_has_started_up)
prog_argc = argc;
prog_argv = argv;
-#if defined(PAR)
+#ifdef PAR
/* Initialise the parallel system -- before initHeap! */
initParallelSystem();
/* And start GranSim profiling if required: omitted for now
initProfiling();
#endif
+ /* start the ticker */
+ install_vtalrm_handler();
+ initialize_virtual_timer(TICK_MILLISECS);
+
/* Initialise the scheduler */
initScheduler();
/* Initialise the stats department */
initStats();
-#if 0
+#if !defined(mingw32_TARGET_OS) && !defined(PAR)
+ /* Initialise the user signal handler set */
initUserSignals();
+ /* Set up handler to run on SIGINT */
+ init_shutdown_handler();
#endif
/* When the RTS and Prelude live in separate DLLs,
filling in the tables with references to where the
static info tables have been loaded inside the running
process.
-
- Ditto for Bool closure tbl.
*/
-#ifdef HAVE_WIN32_DLL_SUPPORT
+#ifdef ENABLE_WIN32_DLL_SUPPORT
for(i=0;i<=255;i++)
(CHARLIKE_closure[i]).header.info = (const StgInfoTable*)&Czh_static_info;
for(i=0;i<=32;i++)
(INTLIKE_closure[i]).header.info = (const StgInfoTable*)&Izh_static_info;
- PrelBase_Bool_closure_tbl[0] = (const StgClosure*)&False_closure;
- PrelBase_Bool_closure_tbl[1] = (const StgClosure*)&True_closure;
#endif
/* Record initialization times */
end_init();
}
+/*
+ * Shutting down the RTS - two ways of doing this, one which
+ * calls exit(), one that doesn't.
+ *
+ * (shutdownHaskellAndExit() is called by System.exitWith).
+ */
+void
+shutdownHaskellAndExit(int n)
+{
+ OnExitHook();
+ shutdownHaskell();
+ stg_exit(n);
+}
+
void
shutdownHaskell(void)
{
+ if (!rts_has_started_up)
+ return;
+
/* Finalize any remaining weak pointers */
finalizeWeakPointersNow();
/* clean up things from the storage manager's point of view */
exitStorage();
+ /* stop the ticker */
+ initialize_virtual_timer(0);
+
#if defined(PROFILING) || defined(DEBUG)
endProfiling();
#endif
if (RtsFlags.TickyFlags.showTickyStats) PrintTickyInfo();
#endif
- /*
- This fflush is important, because: if "main" just returns,
- then we will end up in pre-supplied exit code that will close
- streams and flush buffers. In particular we have seen: it
- will close fd 0 (stdin), then flush fd 1 (stdout), then <who
- cares>...
-
- But if you're playing with sockets, that "close fd 0" might
- suggest to the daemon that all is over, only to be presented
- with more stuff on "fd 1" at the flush.
-
- The fflush avoids this sad possibility.
- */
- fflush(stdout);
+ rts_has_started_up=0;
}
/*
- * called from STG-land to exit the program cleanly
+ * called from STG-land to exit the program
*/
void
#ifdef PAR
par_exit(n);
#else
- OnExitHook();
exit(n);
#endif
}
+