1 /* ----------------------------------------------------------------------------
2  *
3  * (c) The GHC Team, 1998-2001
4  *
5  * API for invoking Haskell functions via the RTS
6  *
7  * --------------------------------------------------------------------------*/
8 
9 #include "PosixSource.h"
10 #include "Rts.h"
11 #include "RtsAPI.h"
12 #include "HsFFI.h"
13 
14 #include "RtsUtils.h"
15 #include "Prelude.h"
16 #include "Schedule.h"
17 #include "Capability.h"
18 #include "StablePtr.h"
19 #include "Threads.h"
20 #include "Weak.h"
21 
22 /* ----------------------------------------------------------------------------
23    Building Haskell objects from C datatypes.
24 
25    TODO: Currently this code does not tag created pointers,
26          however it is not unsafe (the constructor code will do it)
27          just inefficient.
28    ------------------------------------------------------------------------- */
29 HaskellObj
rts_mkChar(Capability * cap,HsChar c)30 rts_mkChar (Capability *cap, HsChar c)
31 {
32   StgClosure *p = (StgClosure *)allocate(cap, CONSTR_sizeW(0,1));
33   SET_HDR(p, Czh_con_info, CCS_SYSTEM);
34   p->payload[0]  = (StgClosure *)(StgWord)(StgChar)c;
35   return p;
36 }
37 
38 HaskellObj
rts_mkInt(Capability * cap,HsInt i)39 rts_mkInt (Capability *cap, HsInt i)
40 {
41   StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,1));
42   SET_HDR(p, Izh_con_info, CCS_SYSTEM);
43   p->payload[0]  = (StgClosure *)(StgInt)i;
44   return p;
45 }
46 
47 HaskellObj
rts_mkInt8(Capability * cap,HsInt8 i)48 rts_mkInt8 (Capability *cap, HsInt8 i)
49 {
50   StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,1));
51   SET_HDR(p, I8zh_con_info, CCS_SYSTEM);
52   /* Make sure we mask out the bits above the lowest 8 */
53   p->payload[0]  = (StgClosure *)(StgInt)i;
54   return p;
55 }
56 
57 HaskellObj
rts_mkInt16(Capability * cap,HsInt16 i)58 rts_mkInt16 (Capability *cap, HsInt16 i)
59 {
60   StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,1));
61   SET_HDR(p, I16zh_con_info, CCS_SYSTEM);
62   /* Make sure we mask out the relevant bits */
63   p->payload[0]  = (StgClosure *)(StgInt)i;
64   return p;
65 }
66 
67 HaskellObj
rts_mkInt32(Capability * cap,HsInt32 i)68 rts_mkInt32 (Capability *cap, HsInt32 i)
69 {
70   StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,1));
71   SET_HDR(p, I32zh_con_info, CCS_SYSTEM);
72   p->payload[0]  = (StgClosure *)(StgInt)i;
73   return p;
74 }
75 
76 HaskellObj
rts_mkInt64(Capability * cap,HsInt64 i)77 rts_mkInt64 (Capability *cap, HsInt64 i)
78 {
79   StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,2));
80   SET_HDR(p, I64zh_con_info, CCS_SYSTEM);
81   ASSIGN_Int64((P_)&(p->payload[0]), i);
82   return p;
83 }
84 
85 HaskellObj
rts_mkWord(Capability * cap,HsWord i)86 rts_mkWord (Capability *cap, HsWord i)
87 {
88   StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,1));
89   SET_HDR(p, Wzh_con_info, CCS_SYSTEM);
90   p->payload[0]  = (StgClosure *)(StgWord)i;
91   return p;
92 }
93 
94 HaskellObj
rts_mkWord8(Capability * cap,HsWord8 w)95 rts_mkWord8 (Capability *cap, HsWord8 w)
96 {
97   /* see rts_mkInt* comments */
98   StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,1));
99   SET_HDR(p, W8zh_con_info, CCS_SYSTEM);
100   p->payload[0]  = (StgClosure *)(StgWord)(w & 0xff);
101   return p;
102 }
103 
104 HaskellObj
rts_mkWord16(Capability * cap,HsWord16 w)105 rts_mkWord16 (Capability *cap, HsWord16 w)
106 {
107   /* see rts_mkInt* comments */
108   StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,1));
109   SET_HDR(p, W16zh_con_info, CCS_SYSTEM);
110   p->payload[0]  = (StgClosure *)(StgWord)(w & 0xffff);
111   return p;
112 }
113 
114 HaskellObj
rts_mkWord32(Capability * cap,HsWord32 w)115 rts_mkWord32 (Capability *cap, HsWord32 w)
116 {
117   /* see rts_mkInt* comments */
118   StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,1));
119   SET_HDR(p, W32zh_con_info, CCS_SYSTEM);
120   p->payload[0]  = (StgClosure *)(StgWord)(w & 0xffffffff);
121   return p;
122 }
123 
124 HaskellObj
rts_mkWord64(Capability * cap,HsWord64 w)125 rts_mkWord64 (Capability *cap, HsWord64 w)
126 {
127   StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,2));
128   /* see mk_Int8 comment */
129   SET_HDR(p, W64zh_con_info, CCS_SYSTEM);
130   ASSIGN_Word64((P_)&(p->payload[0]), w);
131   return p;
132 }
133 
134 
135 HaskellObj
rts_mkFloat(Capability * cap,HsFloat f)136 rts_mkFloat (Capability *cap, HsFloat f)
137 {
138   StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,1));
139   SET_HDR(p, Fzh_con_info, CCS_SYSTEM);
140   ASSIGN_FLT((P_)p->payload, (StgFloat)f);
141   return p;
142 }
143 
144 HaskellObj
rts_mkDouble(Capability * cap,HsDouble d)145 rts_mkDouble (Capability *cap, HsDouble d)
146 {
147   StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,sizeofW(StgDouble)));
148   SET_HDR(p, Dzh_con_info, CCS_SYSTEM);
149   ASSIGN_DBL((P_)p->payload, (StgDouble)d);
150   return p;
151 }
152 
153 HaskellObj
rts_mkStablePtr(Capability * cap,HsStablePtr s)154 rts_mkStablePtr (Capability *cap, HsStablePtr s)
155 {
156   StgClosure *p = (StgClosure *)allocate(cap,sizeofW(StgHeader)+1);
157   SET_HDR(p, StablePtr_con_info, CCS_SYSTEM);
158   p->payload[0]  = (StgClosure *)s;
159   return p;
160 }
161 
162 HaskellObj
rts_mkPtr(Capability * cap,HsPtr a)163 rts_mkPtr (Capability *cap, HsPtr a)
164 {
165   StgClosure *p = (StgClosure *)allocate(cap,sizeofW(StgHeader)+1);
166   SET_HDR(p, Ptr_con_info, CCS_SYSTEM);
167   p->payload[0]  = (StgClosure *)a;
168   return p;
169 }
170 
171 HaskellObj
rts_mkFunPtr(Capability * cap,HsFunPtr a)172 rts_mkFunPtr (Capability *cap, HsFunPtr a)
173 {
174   StgClosure *p = (StgClosure *)allocate(cap,sizeofW(StgHeader)+1);
175   SET_HDR(p, FunPtr_con_info, CCS_SYSTEM);
176   p->payload[0]  = (StgClosure *)a;
177   return p;
178 }
179 
180 HaskellObj
rts_mkBool(Capability * cap STG_UNUSED,HsBool b)181 rts_mkBool (Capability *cap STG_UNUSED, HsBool b)
182 {
183   if (b) {
184     return (StgClosure *)True_closure;
185   } else {
186     return (StgClosure *)False_closure;
187   }
188 }
189 
190 HaskellObj
rts_mkString(Capability * cap,char * s)191 rts_mkString (Capability *cap, char *s)
192 {
193   return rts_apply(cap, (StgClosure *)unpackCString_closure, rts_mkPtr(cap,s));
194 }
195 
196 HaskellObj
rts_apply(Capability * cap,HaskellObj f,HaskellObj arg)197 rts_apply (Capability *cap, HaskellObj f, HaskellObj arg)
198 {
199     StgThunk *ap;
200 
201     ap = (StgThunk *)allocate(cap,sizeofW(StgThunk) + 2);
202     // Here we don't want to use CCS_SYSTEM, because it's a hidden cost centre,
203     // and evaluating Haskell code under a hidden cost centre leads to
204     // confusing profiling output. (#7753)
205     SET_HDR(ap, (StgInfoTable *)&stg_ap_2_upd_info, CCS_MAIN);
206     ap->payload[0] = f;
207     ap->payload[1] = arg;
208     return (StgClosure *)ap;
209 }
210 
211 /* ----------------------------------------------------------------------------
212    Deconstructing Haskell objects
213 
214    We would like to assert that we have the right kind of object in
215    each case, but this is problematic because in GHCi the info table
216    for the D# constructor (say) might be dynamically loaded.  Hence we
217    omit these assertions for now.
218    ------------------------------------------------------------------------- */
219 
220 HsChar
rts_getChar(HaskellObj p)221 rts_getChar (HaskellObj p)
222 {
223     // See comment above:
224     // ASSERT(p->header.info == Czh_con_info ||
225     //        p->header.info == Czh_static_info);
226     return (StgChar)(StgWord)(UNTAG_CLOSURE(p)->payload[0]);
227 }
228 
229 HsInt
rts_getInt(HaskellObj p)230 rts_getInt (HaskellObj p)
231 {
232     // See comment above:
233     // ASSERT(p->header.info == Izh_con_info ||
234     //        p->header.info == Izh_static_info);
235     return (HsInt)(UNTAG_CLOSURE(p)->payload[0]);
236 }
237 
238 HsInt8
rts_getInt8(HaskellObj p)239 rts_getInt8 (HaskellObj p)
240 {
241     // See comment above:
242     // ASSERT(p->header.info == I8zh_con_info ||
243     //        p->header.info == I8zh_static_info);
244     return (HsInt8)(HsInt)(UNTAG_CLOSURE(p)->payload[0]);
245 }
246 
247 HsInt16
rts_getInt16(HaskellObj p)248 rts_getInt16 (HaskellObj p)
249 {
250     // See comment above:
251     // ASSERT(p->header.info == I16zh_con_info ||
252     //        p->header.info == I16zh_static_info);
253     return (HsInt16)(HsInt)(UNTAG_CLOSURE(p)->payload[0]);
254 }
255 
256 HsInt32
rts_getInt32(HaskellObj p)257 rts_getInt32 (HaskellObj p)
258 {
259     // See comment above:
260     // ASSERT(p->header.info == I32zh_con_info ||
261     //        p->header.info == I32zh_static_info);
262   return (HsInt32)(HsInt)(UNTAG_CLOSURE(p)->payload[0]);
263 }
264 
265 HsInt64
rts_getInt64(HaskellObj p)266 rts_getInt64 (HaskellObj p)
267 {
268     // See comment above:
269     // ASSERT(p->header.info == I64zh_con_info ||
270     //        p->header.info == I64zh_static_info);
271     return PK_Int64((P_)&(UNTAG_CLOSURE(p)->payload[0]));
272 }
273 
274 HsWord
rts_getWord(HaskellObj p)275 rts_getWord (HaskellObj p)
276 {
277     // See comment above:
278     // ASSERT(p->header.info == Wzh_con_info ||
279     //        p->header.info == Wzh_static_info);
280     return (HsWord)(UNTAG_CLOSURE(p)->payload[0]);
281 }
282 
283 HsWord8
rts_getWord8(HaskellObj p)284 rts_getWord8 (HaskellObj p)
285 {
286     // See comment above:
287     // ASSERT(p->header.info == W8zh_con_info ||
288     //        p->header.info == W8zh_static_info);
289     return (HsWord8)(HsWord)(UNTAG_CLOSURE(p)->payload[0]);
290 }
291 
292 HsWord16
rts_getWord16(HaskellObj p)293 rts_getWord16 (HaskellObj p)
294 {
295     // See comment above:
296     // ASSERT(p->header.info == W16zh_con_info ||
297     //        p->header.info == W16zh_static_info);
298     return (HsWord16)(HsWord)(UNTAG_CLOSURE(p)->payload[0]);
299 }
300 
301 HsWord32
rts_getWord32(HaskellObj p)302 rts_getWord32 (HaskellObj p)
303 {
304     // See comment above:
305     // ASSERT(p->header.info == W32zh_con_info ||
306     //        p->header.info == W32zh_static_info);
307     return (HsWord32)(HsWord)(UNTAG_CLOSURE(p)->payload[0]);
308 }
309 
310 HsWord64
rts_getWord64(HaskellObj p)311 rts_getWord64 (HaskellObj p)
312 {
313     // See comment above:
314     // ASSERT(p->header.info == W64zh_con_info ||
315     //        p->header.info == W64zh_static_info);
316     return PK_Word64((P_)&(UNTAG_CLOSURE(p)->payload[0]));
317 }
318 
319 HsFloat
rts_getFloat(HaskellObj p)320 rts_getFloat (HaskellObj p)
321 {
322     // See comment above:
323     // ASSERT(p->header.info == Fzh_con_info ||
324     //        p->header.info == Fzh_static_info);
325     return (float)(PK_FLT((P_)UNTAG_CLOSURE(p)->payload));
326 }
327 
328 HsDouble
rts_getDouble(HaskellObj p)329 rts_getDouble (HaskellObj p)
330 {
331     // See comment above:
332     // ASSERT(p->header.info == Dzh_con_info ||
333     //        p->header.info == Dzh_static_info);
334     return (double)(PK_DBL((P_)UNTAG_CLOSURE(p)->payload));
335 }
336 
337 HsStablePtr
rts_getStablePtr(HaskellObj p)338 rts_getStablePtr (HaskellObj p)
339 {
340     // See comment above:
341     // ASSERT(p->header.info == StablePtr_con_info ||
342     //        p->header.info == StablePtr_static_info);
343     return (StgStablePtr)(UNTAG_CLOSURE(p)->payload[0]);
344 }
345 
346 HsPtr
rts_getPtr(HaskellObj p)347 rts_getPtr (HaskellObj p)
348 {
349     // See comment above:
350     // ASSERT(p->header.info == Ptr_con_info ||
351     //        p->header.info == Ptr_static_info);
352     return (Capability *)(UNTAG_CLOSURE(p)->payload[0]);
353 }
354 
355 HsFunPtr
rts_getFunPtr(HaskellObj p)356 rts_getFunPtr (HaskellObj p)
357 {
358     // See comment above:
359     // ASSERT(p->header.info == FunPtr_con_info ||
360     //        p->header.info == FunPtr_static_info);
361     return (void *)(UNTAG_CLOSURE(p)->payload[0]);
362 }
363 
364 HsBool
rts_getBool(HaskellObj p)365 rts_getBool (HaskellObj p)
366 {
367     const StgInfoTable *info;
368 
369     info = get_itbl((const StgClosure *)UNTAG_CONST_CLOSURE(p));
370     if (info->srt == 0) { // srt is the constructor tag
371         return 0;
372     } else {
373         return 1;
374     }
375 }
376 
377 /* -----------------------------------------------------------------------------
378    Creating threads
379    -------------------------------------------------------------------------- */
380 
pushClosure(StgTSO * tso,StgWord c)381 INLINE_HEADER void pushClosure   (StgTSO *tso, StgWord c) {
382   tso->stackobj->sp--;
383   tso->stackobj->sp[0] = (W_) c;
384 }
385 
386 StgTSO *
createGenThread(Capability * cap,W_ stack_size,StgClosure * closure)387 createGenThread (Capability *cap, W_ stack_size,  StgClosure *closure)
388 {
389   StgTSO *t;
390   t = createThread (cap, stack_size);
391   pushClosure(t, (W_)closure);
392   pushClosure(t, (W_)&stg_enter_info);
393   return t;
394 }
395 
396 StgTSO *
createIOThread(Capability * cap,W_ stack_size,StgClosure * closure)397 createIOThread (Capability *cap, W_ stack_size,  StgClosure *closure)
398 {
399   StgTSO *t;
400   t = createThread (cap, stack_size);
401   pushClosure(t, (W_)&stg_ap_v_info);
402   pushClosure(t, (W_)closure);
403   pushClosure(t, (W_)&stg_enter_info);
404   return t;
405 }
406 
407 /*
408  * Same as above, but also evaluate the result of the IO action
409  * to whnf while we're at it.
410  */
411 
412 StgTSO *
createStrictIOThread(Capability * cap,W_ stack_size,StgClosure * closure)413 createStrictIOThread(Capability *cap, W_ stack_size,  StgClosure *closure)
414 {
415   StgTSO *t;
416   t = createThread(cap, stack_size);
417   pushClosure(t, (W_)&stg_forceIO_info);
418   pushClosure(t, (W_)&stg_ap_v_info);
419   pushClosure(t, (W_)closure);
420   pushClosure(t, (W_)&stg_enter_info);
421   return t;
422 }
423 
424 /* ----------------------------------------------------------------------------
425    Evaluating Haskell expressions
426    ------------------------------------------------------------------------- */
427 
rts_eval(Capability ** cap,HaskellObj p,HaskellObj * ret)428 void rts_eval (/* inout */ Capability **cap,
429                /* in    */ HaskellObj p,
430                /* out */   HaskellObj *ret)
431 {
432     StgTSO *tso;
433 
434     tso = createGenThread(*cap, RtsFlags.GcFlags.initialStkSize, p);
435     scheduleWaitThread(tso,ret,cap);
436 }
437 
rts_eval_(Capability ** cap,HaskellObj p,unsigned int stack_size,HaskellObj * ret)438 void rts_eval_ (/* inout */ Capability **cap,
439                 /* in    */ HaskellObj p,
440                 /* in    */ unsigned int stack_size,
441                 /* out   */ HaskellObj *ret)
442 {
443     StgTSO *tso;
444 
445     tso = createGenThread(*cap, stack_size, p);
446     scheduleWaitThread(tso,ret,cap);
447 }
448 
449 /*
450  * rts_evalIO() evaluates a value of the form (IO a), forcing the action's
451  * result to WHNF before returning.
452  */
rts_evalIO(Capability ** cap,HaskellObj p,HaskellObj * ret)453 void rts_evalIO (/* inout */ Capability **cap,
454                  /* in    */ HaskellObj p,
455                  /* out */   HaskellObj *ret)
456 {
457     StgTSO* tso;
458 
459     tso = createStrictIOThread(*cap, RtsFlags.GcFlags.initialStkSize, p);
460     scheduleWaitThread(tso,ret,cap);
461 }
462 
463 /*
464  * rts_evalStableIOMain() is suitable for calling main Haskell thread
465  * stored in (StablePtr (IO a)) it calls rts_evalStableIO but wraps
466  * function in GHC.TopHandler.runMainIO that installs top_handlers.
467  * See #12903.
468  */
rts_evalStableIOMain(Capability ** cap,HsStablePtr s,HsStablePtr * ret)469 void rts_evalStableIOMain(/* inout */ Capability **cap,
470                           /* in    */ HsStablePtr s,
471                           /* out   */ HsStablePtr *ret)
472 {
473     StgTSO* tso;
474     StgClosure *p, *r, *w;
475     SchedulerStatus stat;
476 
477     p = (StgClosure *)deRefStablePtr(s);
478     w = rts_apply(*cap, &base_GHCziTopHandler_runMainIO_closure, p);
479     tso = createStrictIOThread(*cap, RtsFlags.GcFlags.initialStkSize, w);
480     // async exceptions are always blocked by default in the created
481     // thread.  See #1048.
482     tso->flags |= TSO_BLOCKEX | TSO_INTERRUPTIBLE;
483     scheduleWaitThread(tso,&r,cap);
484     stat = rts_getSchedStatus(*cap);
485 
486     if (stat == Success && ret != NULL) {
487         ASSERT(r != NULL);
488         *ret = getStablePtr((StgPtr)r);
489     }
490 }
491 
492 /*
493  * rts_evalStableIO() is suitable for calling from Haskell.  It
494  * evaluates a value of the form (StablePtr (IO a)), forcing the
495  * action's result to WHNF before returning.  The result is returned
496  * in a StablePtr.
497  */
rts_evalStableIO(Capability ** cap,HsStablePtr s,HsStablePtr * ret)498 void rts_evalStableIO (/* inout */ Capability **cap,
499                        /* in    */ HsStablePtr s,
500                        /* out */   HsStablePtr *ret)
501 {
502     StgTSO* tso;
503     StgClosure *p, *r;
504     SchedulerStatus stat;
505 
506     p = (StgClosure *)deRefStablePtr(s);
507     tso = createStrictIOThread(*cap, RtsFlags.GcFlags.initialStkSize, p);
508     // async exceptions are always blocked by default in the created
509     // thread.  See #1048.
510     tso->flags |= TSO_BLOCKEX | TSO_INTERRUPTIBLE;
511     scheduleWaitThread(tso,&r,cap);
512     stat = rts_getSchedStatus(*cap);
513 
514     if (stat == Success && ret != NULL) {
515         ASSERT(r != NULL);
516         *ret = getStablePtr((StgPtr)r);
517     }
518 }
519 
520 /*
521  * Like rts_evalIO(), but doesn't force the action's result.
522  */
rts_evalLazyIO(Capability ** cap,HaskellObj p,HaskellObj * ret)523 void rts_evalLazyIO (/* inout */ Capability **cap,
524                      /* in    */ HaskellObj p,
525                      /* out */   HaskellObj *ret)
526 {
527     StgTSO *tso;
528 
529     tso = createIOThread(*cap, RtsFlags.GcFlags.initialStkSize, p);
530     scheduleWaitThread(tso,ret,cap);
531 }
532 
rts_evalLazyIO_(Capability ** cap,HaskellObj p,unsigned int stack_size,HaskellObj * ret)533 void rts_evalLazyIO_ (/* inout */ Capability **cap,
534                       /* in    */ HaskellObj p,
535                       /* in    */ unsigned int stack_size,
536                       /* out   */ HaskellObj *ret)
537 {
538     StgTSO *tso;
539 
540     tso = createIOThread(*cap, stack_size, p);
541     scheduleWaitThread(tso,ret,cap);
542 }
543 
544 /* Convenience function for decoding the returned status. */
545 
546 void
rts_checkSchedStatus(char * site,Capability * cap)547 rts_checkSchedStatus (char* site, Capability *cap)
548 {
549     SchedulerStatus rc = cap->running_task->incall->rstat;
550     switch (rc) {
551     case Success:
552         return;
553     case Killed:
554         errorBelch("%s: uncaught exception",site);
555         stg_exit(EXIT_FAILURE);
556     case Interrupted:
557         errorBelch("%s: interrupted", site);
558 #if defined(THREADED_RTS)
559         // The RTS is shutting down, and the process will probably
560         // soon exit.  We don't want to preempt the shutdown
561         // by exiting the whole process here, so we just terminate the
562         // current thread.  Don't forget to release the cap first though.
563         rts_unlock(cap);
564         shutdownThread();
565 #else
566         stg_exit(EXIT_FAILURE);
567 #endif
568     default:
569         errorBelch("%s: Return code (%d) not ok",(site),(rc));
570         stg_exit(EXIT_FAILURE);
571     }
572 }
573 
574 SchedulerStatus
rts_getSchedStatus(Capability * cap)575 rts_getSchedStatus (Capability *cap)
576 {
577     return cap->running_task->incall->rstat;
578 }
579 
580 Capability *
rts_lock(void)581 rts_lock (void)
582 {
583     Capability *cap;
584     Task *task;
585 
586     task = newBoundTask();
587 
588     if (task->running_finalizers) {
589         errorBelch("error: a C finalizer called back into Haskell.\n"
590                    "   This was previously allowed, but is disallowed in GHC 6.10.2 and later.\n"
591                    "   To create finalizers that may call back into Haskell, use\n"
592                    "   Foreign.Concurrent.newForeignPtr instead of Foreign.newForeignPtr.");
593         stg_exit(EXIT_FAILURE);
594     }
595 
596     cap = NULL;
597     waitForCapability(&cap, task);
598 
599     if (task->incall->prev_stack == NULL) {
600       // This is a new outermost call from C into Haskell land.
601       // Until the corresponding call to rts_unlock, this task
602       // is doing work on behalf of the RTS.
603       traceTaskCreate(task, cap);
604     }
605 
606     return (Capability *)cap;
607 }
608 
609 // Exiting the RTS: we hold a Capability that is not necessarily the
610 // same one that was originally returned by rts_lock(), because
611 // rts_evalIO() etc. may return a new one.  Now that we have
612 // investigated the return value, we can release the Capability,
613 // and free the Task (in that order).
614 
615 void
rts_unlock(Capability * cap)616 rts_unlock (Capability *cap)
617 {
618     Task *task;
619 
620     task = cap->running_task;
621     ASSERT_FULL_CAPABILITY_INVARIANTS(cap,task);
622 
623     // Now release the Capability.  With the capability released, GC
624     // may happen.  NB. does not try to put the current Task on the
625     // worker queue.
626     // NB. keep cap->lock held while we call boundTaskExiting().  This
627     // is necessary during shutdown, where we want the invariant that
628     // after shutdownCapability(), all the Tasks associated with the
629     // Capability have completed their shutdown too.  Otherwise we
630     // could have boundTaskExiting()/workerTaskStop() running at some
631     // random point in the future, which causes problems for
632     // freeTaskManager().
633     ACQUIRE_LOCK(&cap->lock);
634     releaseCapability_(cap,false);
635 
636     // Finally, we can release the Task to the free list.
637     boundTaskExiting(task);
638     RELEASE_LOCK(&cap->lock);
639 
640     if (task->incall == NULL) {
641       // This is the end of an outermost call from C into Haskell land.
642       // From here on, the task goes back to C land and we should not count
643       // it as doing work on behalf of the RTS.
644       traceTaskDelete(task);
645     }
646 }
647 
rts_done(void)648 void rts_done (void)
649 {
650     freeMyTask();
651 }
652 
653 /* -----------------------------------------------------------------------------
654    tryPutMVar from outside Haskell
655 
656    The C call
657 
658       hs_try_putmvar(cap, mvar)
659 
660    is equivalent to the Haskell call
661 
662       tryPutMVar mvar ()
663 
664    but it is
665 
666      * non-blocking: takes a bounded, short, amount of time
667      * asynchronous: the actual putMVar may be performed after the
668        call returns.  That's why hs_try_putmvar() doesn't return a
669        result to say whether the put succeeded.
670 
671    NOTE: this call transfers ownership of the StablePtr to the RTS, which will
672    free it after the tryPutMVar has taken place.  The reason is that otherwise,
673    it would be very difficult for the caller to arrange to free the StablePtr
674    in all circumstances.
675 
676    For more details, see the section "Waking up Haskell threads from C" in the
677    User's Guide.
678    -------------------------------------------------------------------------- */
679 
hs_try_putmvar(int capability,HsStablePtr mvar)680 void hs_try_putmvar (/* in */ int capability,
681                      /* in */ HsStablePtr mvar)
682 {
683     Task *task = getTask();
684     Capability *cap;
685 
686     if (capability < 0) {
687         capability = task->preferred_capability;
688         if (capability < 0) {
689             capability = 0;
690         }
691     }
692     cap = capabilities[capability % enabled_capabilities];
693 
694 #if !defined(THREADED_RTS)
695 
696     performTryPutMVar(cap, (StgMVar*)deRefStablePtr(mvar), Unit_closure);
697     freeStablePtr(mvar);
698 
699 #else
700 
701     ACQUIRE_LOCK(&cap->lock);
702     // If the capability is free, we can perform the tryPutMVar immediately
703     if (cap->running_task == NULL) {
704         cap->running_task = task;
705         task->cap = cap;
706         RELEASE_LOCK(&cap->lock);
707 
708         performTryPutMVar(cap, (StgMVar*)deRefStablePtr(mvar), Unit_closure);
709 
710         freeStablePtr(mvar);
711 
712         // Wake up the capability, which will start running the thread that we
713         // just awoke (if there was one).
714         releaseCapability(cap);
715     } else {
716         PutMVar *p = stgMallocBytes(sizeof(PutMVar),"hs_try_putmvar");
717         // We cannot deref the StablePtr if we don't have a capability,
718         // so we have to store it and deref it later.
719         p->mvar = mvar;
720         p->link = cap->putMVars;
721         cap->putMVars = p;
722         RELEASE_LOCK(&cap->lock);
723     }
724 
725 #endif
726 }
727