rts: Add api to pin a thread to a numa node but without fixing a capability
[ghc.git] / rts / StgStartup.cmm
1 /* -----------------------------------------------------------------------------
2  *
3  * (c) The GHC Team, 1998-2012
4  *
5  * Code for starting, stopping and restarting threads.
6  *
7  * This file is written in a subset of C--, extended with various
8  * features specific to GHC.  It is compiled by GHC directly.  For the
9  * syntax of .cmm files, see the parser in ghc/compiler/cmm/CmmParse.y.
10  *
11  * ---------------------------------------------------------------------------*/
12
13 #include "Cmm.h"
14
15 /*
16  * This module contains the two entry points and the final exit point
17  * to/from the Haskell world.  We can enter either by:
18  *
19  *   a) returning to the address on the top of the stack, or
20  *   b) entering the closure on the top of the stack
21  *
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.
25  */
26
27 #define CHECK_SENSIBLE_REGS()                           \
28     ASSERT(Hp != 0);                                    \
29     ASSERT(HpAlloc == 0);                               \
30     ASSERT(Sp != 0);                                    \
31     ASSERT(SpLim != 0);                                 \
32     ASSERT(SpLim - WDS(RESERVED_STACK_WORDS) <= Sp);
33
34 /* -----------------------------------------------------------------------------
35    Returning from the STG world.
36    -------------------------------------------------------------------------- */
37
38 INFO_TABLE_RET(stg_stop_thread, STOP_FRAME,
39                W_ info_ptr,
40                PROF_HDR_FIELDS(W_,p1,p2))
41 /* no return list: explicit stack layout */
42 {
43     /*
44        The final exit.
45
46        The top-top-level closures (e.g., "main") are of type "IO a".
47        When entered, they perform an IO action and return an 'a' in R1.
48
49        We save R1 on top of the stack where the scheduler can find it,
50        tidy up the registers and return to the scheduler.
51
52        We Leave the stack looking like this:
53
54                 +----------------+
55                 |      -------------------> return value
56                 +----------------+
57                 | stg_enter_info |
58                 +----------------+
59
60        The stg_enter_info is just a dummy info table so that the
61        garbage collector can understand the stack (there must always
62        be an info table on top of the stack).
63     */
64
65     /*
66        Here we setup the stack unwinding annotation necessary to allow
67        debuggers to find their way back to the C stack.
68
69        This is a bit fiddly as we assume the layout of the stack prepared
70        for us by StgRun.
71      */
72 #ifdef x86_64_HOST_ARCH
73     unwind MachSp = MachSp + RESERVED_C_STACK_BYTES + 0x38 + 8
74     unwind UnwindReturnReg = W_[MachSp + RESERVED_C_STACK_BYTES + 0x38]
75 #endif
76
77     Sp = Sp + SIZEOF_StgStopFrame - WDS(2);
78     Sp(1) = R1;
79     Sp(0) = stg_enter_info;
80
81     StgTSO_what_next(CurrentTSO) = ThreadComplete::I16;
82
83     SAVE_THREAD_STATE();
84
85     /* The return code goes in BaseReg->rRet, and BaseReg is returned in R1 */
86     StgRegTable_rRet(BaseReg) = ThreadFinished;
87     R1 = BaseReg;
88
89     jump StgReturn [R1];
90 }
91
92 /* -----------------------------------------------------------------------------
93    Start a thread from the scheduler by returning to the address on
94    the top of the stack.  This is used for all entries to STG code
95    from C land.
96
97    On the way back, we (usually) pass through stg_returnToSched which saves
98    the thread's state away nicely.
99    -------------------------------------------------------------------------- */
100
101 stg_returnToStackTop /* no args: explicit stack layout */
102 {
103   LOAD_THREAD_STATE();
104   CHECK_SENSIBLE_REGS();
105   jump %ENTRY_CODE(Sp(0)) [];
106 }
107
108 stg_returnToSched /* no args: explicit stack layout */
109 {
110   W_ r1;
111   r1 = R1; // foreign calls may clobber R1
112   SAVE_THREAD_STATE();
113   foreign "C" threadPaused(MyCapability() "ptr", CurrentTSO);
114   R1 = r1;
115   jump StgReturn [R1];
116 }
117
118 // A variant of stg_returnToSched that doesn't call threadPaused() on the
119 // current thread.  This is used for switching from compiled execution to the
120 // interpreter, where calling threadPaused() on every switch would be too
121 // expensive.
122 stg_returnToSchedNotPaused /* no args: explicit stack layout */
123 {
124   SAVE_THREAD_STATE();
125   jump StgReturn [R1];
126 }
127
128 // A variant of stg_returnToSched, but instead of returning directly to the
129 // scheduler, we jump to the code fragment pointed to by R2.  This lets us
130 // perform some final actions after making the thread safe, such as unlocking
131 // the MVar on which we are about to block in SMP mode.
132 stg_returnToSchedButFirst /* no args: explicit stack layout */
133 {
134   W_ r1, r2, r3;
135   r1 = R1;
136   r2 = R2;
137   r3 = R3;
138   SAVE_THREAD_STATE();
139   // foreign calls may clobber R1/R2/.., so we save them above
140   foreign "C" threadPaused(MyCapability() "ptr", CurrentTSO);
141   R1 = r1;
142   R2 = r2;
143   R3 = r3;
144   jump R2 [R1,R3];
145 }
146
147 stg_threadFinished /* no args: explicit stack layout */
148 {
149   StgRegTable_rRet(BaseReg) = ThreadFinished;
150   R1 = BaseReg;
151   jump StgReturn [R1];
152 }
153
154 /* -----------------------------------------------------------------------------
155     Strict IO application - performing an IO action and entering its result.
156
157     rts_evalIO() lets you perform Haskell IO actions from outside of
158     Haskell-land, returning back to you their result. Want this result
159     to be evaluated to WHNF by that time, so that we can easily get at
160     the int/char/whatever using the various get{Ty} functions provided
161     by the RTS API.
162
163     stg_forceIO takes care of this, performing the IO action and entering
164     the results that comes back.
165
166     ------------------------------------------------------------------------- */
167
168 INFO_TABLE_RET(stg_forceIO, RET_SMALL, P_ info_ptr)
169     return (P_ ret)
170 {
171     ENTER(ret);
172 }
173
174 /* -----------------------------------------------------------------------------
175    Special STG entry points for module registration.
176    -------------------------------------------------------------------------- */
177
178 stg_init_finish /* no args: explicit stack layout */
179 {
180   jump StgReturn [];
181 }
182
183 /* On entry to stg_init:
184  *    init_stack[0] = &stg_init_ret;
185  *    init_stack[1] = __stginit_Something;
186  */
187 stg_init /* no args: explicit stack layout */
188 {
189   W_ next;
190   Sp = W_[BaseReg + OFFSET_StgRegTable_rSp];
191   next = W_[Sp];
192   Sp_adj(1);
193   jump next [];
194 }