1 /* -----------------------------------------------------------------------------
2 * $Id: StgStartup.hc,v 1.21 2003/05/14 09:14:00 simonmar Exp $
4 * (c) The GHC Team, 1998-2002
6 * Code for starting, stopping and restarting threads.
8 * ---------------------------------------------------------------------------*/
12 #include "StgRun.h" /* StgReturn */
13 #include "StgStartup.h"
16 * This module contains the two entry points and the final exit point
17 * to/from the Haskell world. We can enter either by:
19 * a) returning to the address on the top of the stack, or
20 * b) entering the closure on the top of the stack
22 * the function stg_stop_thread_entry is the final exit for a
23 * thread: it is the last return address on the stack. It returns
24 * to the scheduler marking the thread as finished.
27 #define CHECK_SENSIBLE_REGS() \
28 ASSERT(Hp != (P_)0); \
29 ASSERT(Sp != (P_)0); \
30 ASSERT(SpLim != (P_)0); \
31 ASSERT(HpLim != (P_)0); \
32 ASSERT(SpLim - RESERVED_STACK_WORDS <= Sp); \
35 /* -----------------------------------------------------------------------------
36 Returning from the STG world.
38 This is a polymorphic return address, meaning that any old constructor
39 can be returned, we don't care (actually, it's probably going to be
40 an IOok constructor, which will indirect through the vector table
42 -------------------------------------------------------------------------- */
44 EXTFUN(stg_stop_thread_ret);
46 #if defined(PROFILING)
47 #define STOP_THREAD_BITMAP 3
48 #define STOP_THREAD_WORDS 2
50 #define STOP_THREAD_BITMAP 0
51 #define STOP_THREAD_WORDS 0
54 /* VEC_POLY_INFO expects to see these names - but they should all be the same. */
55 #define stg_stop_thread_0_ret stg_stop_thread_ret
56 #define stg_stop_thread_1_ret stg_stop_thread_ret
57 #define stg_stop_thread_2_ret stg_stop_thread_ret
58 #define stg_stop_thread_3_ret stg_stop_thread_ret
59 #define stg_stop_thread_4_ret stg_stop_thread_ret
60 #define stg_stop_thread_5_ret stg_stop_thread_ret
61 #define stg_stop_thread_6_ret stg_stop_thread_ret
62 #define stg_stop_thread_7_ret stg_stop_thread_ret
64 VEC_POLY_INFO_TABLE( stg_stop_thread,
65 MK_SMALL_BITMAP(STOP_THREAD_WORDS, STOP_THREAD_BITMAP),
66 0,0,0,STOP_FRAME,,EF_);
68 STGFUN(stg_stop_thread_ret)
74 // The top-top-level closures (e.g., "main") are of type "IO a".
75 // When entered, they perform an IO action and return an 'a' in R1.
77 // We save R1 on top of the stack where the scheduler can find it,
78 // tidy up the registers and return to the scheduler.
80 // We Leave the stack looking like this:
83 // | -------------------> return value
88 // The stg_enter_info is just a dummy info table so that the
89 // garbage collector can understand the stack (there must always
90 // be an info table on top of the stack).
93 Sp += sizeofW(StgStopFrame) - 2;
95 Sp[0] = (W_)&stg_enter_info;
97 CurrentTSO->what_next = ThreadComplete;
99 SaveThreadState(); // inline!
101 // R1 contains the return value of the thread
102 R1.i = ThreadFinished;
108 /* -----------------------------------------------------------------------------
109 Start a thread from the scheduler by returning to the address on
110 the top of the stack. This is used for all entries to STG code
112 -------------------------------------------------------------------------- */
114 STGFUN(stg_returnToStackTop)
118 CHECK_SENSIBLE_REGS();
119 JMP_(ENTRY_CODE(Sp[0]));
123 /* -----------------------------------------------------------------------------
124 Strict IO application - performing an IO action and entering its result.
126 rts_evalIO() lets you perform Haskell IO actions from outside of
127 Haskell-land, returning back to you their result. Want this result
128 to be evaluated to WHNF by that time, so that we can easily get at
129 the int/char/whatever using the various get{Ty} functions provided
132 forceIO takes care of this, performing the IO action and entering the
133 results that comes back.
134 ------------------------------------------------------------------------- */
136 INFO_TABLE_RET( stg_forceIO_info,stg_forceIO_ret,
137 MK_SMALL_BITMAP(0/*size*/, 0/*BITMAP*/),
138 0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_BITMAP*/,
139 RET_SMALL,, EF_, 0, 0);
142 STGFUN(stg_forceIO_ret)
150 STGFUN(stg_forceIO_ret)
160 /* -----------------------------------------------------------------------------
161 Non-strict IO application.
163 This stack frame works like stg_forceIO_info except that it
164 doesn't evaluate the return value. We need the layer because the
165 return convention for an IO action differs depending on whether R1
166 is a register or not.
167 ------------------------------------------------------------------------- */
169 INFO_TABLE_RET( stg_noforceIO_info,stg_noforceIO_ret,
170 MK_SMALL_BITMAP(0/*size*/, 0/*BITMAP*/),
171 0/*SRT*/, 0/*SRT_OFF*/, 0/*SRT_BITMAP*/,
172 RET_SMALL,, EF_, 0, 0);
175 STGFUN(stg_noforceIO_ret)
179 JMP_(ENTRY_CODE(Sp[0]));
183 STGFUN(stg_noforceIO_ret)
188 JMP_(ENTRY_CODE(Sp[0]));
193 /* -----------------------------------------------------------------------------
194 Special STG entry points for module registration.
195 -------------------------------------------------------------------------- */
197 extern F_ *init_stack;
206 /* On entry to stg_init:
207 * init_stack[0] = &stg_init_ret;
208 * init_stack[1] = __stginit_Something;
214 JMP_(POP_INIT_STACK());