+ // This must be done after module initialisation.
+ // ToDo: make this work in the presence of multiple hs_add_root()s.
+ initProfiling2();
+#endif
+}
+
+/* -----------------------------------------------------------------------------
+ Shutting down the RTS
+ -------------------------------------------------------------------------- */
+
+void
+hs_exit(void)
+{
+ if (hs_init_count <= 0) {
+ barf("too many hs_exit()s");
+ }
+ hs_init_count--;
+ if (hs_init_count > 0) {
+ // ignore until it's the last one
+ return;
+ }
+
+ /* start timing the shutdown */
+ stat_startExit();
+
+ /* stop all running tasks */
+ exitScheduler();
+
+#if !defined(GRAN)
+ /* Finalize any remaining weak pointers */
+ finalizeWeakPointersNow();
+#endif
+
+#if defined(GRAN)
+ /* end_gr_simulation prints global stats if requested -- HWL */
+ if (!RtsFlags.GranFlags.GranSimStats.Suppressed)
+ end_gr_simulation();
+#endif
+
+ /* stop the ticker */
+ stopTimer();
+
+ /* reset the standard file descriptors to blocking mode */
+ resetNonBlockingFd(0);
+ resetNonBlockingFd(1);
+ resetNonBlockingFd(2);
+
+#if defined(PAR)
+ /* controlled exit; good thread! */
+ shutdownParallelSystem(0);
+
+ /* global statistics in parallel system */
+ PAR_TICKY_PAR_END();
+#endif
+
+ /* stop timing the shutdown, we're about to print stats */
+ stat_endExit();
+
+ /* clean up things from the storage manager's point of view.
+ * also outputs the stats (+RTS -s) info.
+ */
+ exitStorage();
+
+#ifdef RTS_GTK_FRONTPANEL
+ if (RtsFlags.GcFlags.frontpanel) {
+ stopFrontPanel();
+ }