+ // 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();
+
+#if !defined(GRAN)
+ /* Finalize any remaining weak pointers */
+ finalizeWeakPointersNow();
+#endif
+
+ /* stop all running tasks */
+ exitScheduler();
+
+#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 HAVE_TERMIOS_H
+ // Reset the terminal settings on the standard file descriptors,
+ // if we changed them. See System.Posix.Internals.tcSetAttr for
+ // more details, including the reason we termporarily disable
+ // SIGTTOU here.
+ {
+ int fd;
+ sigset_t sigset, old_sigset;
+ sigemptyset(&sigset);
+ sigaddset(&sigset, SIGTTOU);
+ sigprocmask(SIG_BLOCK, &sigset, &old_sigset);
+ for (fd = 0; fd <= 2; fd++) {
+ struct termios* ts = (struct termios*)__hscore_get_saved_termios(fd);
+ if (ts != NULL) {
+ tcsetattr(fd,TCSANOW,ts);
+ }
+ }
+ sigprocmask(SIG_SETMASK, &old_sigset, NULL);
+ }
+#endif
+
+#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();
+ }