+extern SchedulerStatus rts_mainLazyIO(HaskellObj p, /*out*/HaskellObj *ret);
+
+
+/* Called by shutdown_handler(). */
+void interruptStgRts ( void );
+
+void raiseAsync(StgTSO *tso, StgClosure *exception);
+nat run_queue_len(void);
+
+void resurrectThreads( StgTSO * );
+
+/* Main threads:
+ *
+ * These are the threads which clients have requested that we run.
+ *
+ * In a 'threaded' build, each of these corresponds to one bound thread.
+ * The pointer to the StgMainThread is passed as a parameter to schedule;
+ * this invocation of schedule will always pass this main thread's
+ * bound_thread_cond to waitForkWorkCapability; OS-thread-switching
+ * takes place using passCapability.
+ *
+ * In non-threaded builds, clients are strictly nested: the first client calls
+ * into the RTS, which might call out again to C with a _ccall_GC, and
+ * eventually re-enter the RTS.
+ *
+ * This is non-abstract at the moment because the garbage collector
+ * treats pointers to TSOs from the main thread list as "weak" - these
+ * pointers won't prevent a thread from receiving a BlockedOnDeadMVar
+ * exception.
+ *
+ * Main threads information is kept in a linked list:
+ */
+typedef struct StgMainThread_ {
+ StgTSO * tso;
+ SchedulerStatus stat;
+ StgClosure ** ret;
+#if defined(RTS_SUPPORTS_THREADS)
+#if defined(THREADED_RTS)
+ Condition bound_thread_cond;
+#else
+ Condition wakeup;
+#endif
+#endif
+ struct StgMainThread_ *prev;
+ struct StgMainThread_ *link;
+} StgMainThread;
+
+/* Main thread queue.
+ * Locks required: sched_mutex.
+ */
+extern StgMainThread *main_threads;
+
+void printAllThreads(void);
+#ifdef COMPILING_SCHEDULER
+static void printThreadBlockage(StgTSO *tso);
+static void printThreadStatus(StgTSO *tso);
+#endif
+/* debugging only
+ */
+#ifdef DEBUG
+void print_bq (StgClosure *node);
+#endif
+#if defined(PAR)
+void print_bqe (StgBlockingQueueElement *bqe);
+#endif
+
+void labelThread(StgPtr tso, char *label);
+
+/* -----------------------------------------------------------------------------
+ * Some convenient macros...
+ */
+
+/* END_TSO_QUEUE and friends now defined in includes/StgMiscClosures.h */
+
+/* Add a thread to the end of the run queue.
+ * NOTE: tso->link should be END_TSO_QUEUE before calling this macro.
+ */
+#define APPEND_TO_RUN_QUEUE(tso) \
+ ASSERT(tso->link == END_TSO_QUEUE); \
+ if (run_queue_hd == END_TSO_QUEUE) { \