1 /* ----------------------------------------------------------------------------
3 * (c) The GHC Team, 1998-2001
5 * API for invoking Haskell functions via the RTS
7 * --------------------------------------------------------------------------*/
9 #include "PosixSource.h"
11 #include "OSThreads.h"
18 #include "Capability.h"
23 /* ----------------------------------------------------------------------------
24 Building Haskell objects from C datatypes.
26 TODO: Currently this code does not tag created pointers,
27 however it is not unsafe (the contructor code will do it)
29 ------------------------------------------------------------------------- */
31 rts_mkChar (Capability *cap, HsChar c)
33 StgClosure *p = (StgClosure *)allocateLocal(cap, CONSTR_sizeW(0,1));
34 SET_HDR(p, Czh_con_info, CCS_SYSTEM);
35 p->payload[0] = (StgClosure *)(StgWord)(StgChar)c;
40 rts_mkInt (Capability *cap, HsInt i)
42 StgClosure *p = (StgClosure *)allocateLocal(cap,CONSTR_sizeW(0,1));
43 SET_HDR(p, Izh_con_info, CCS_SYSTEM);
44 p->payload[0] = (StgClosure *)(StgInt)i;
49 rts_mkInt8 (Capability *cap, HsInt8 i)
51 StgClosure *p = (StgClosure *)allocateLocal(cap,CONSTR_sizeW(0,1));
52 SET_HDR(p, I8zh_con_info, CCS_SYSTEM);
53 /* Make sure we mask out the bits above the lowest 8 */
54 p->payload[0] = (StgClosure *)(StgInt)i;
59 rts_mkInt16 (Capability *cap, HsInt16 i)
61 StgClosure *p = (StgClosure *)allocateLocal(cap,CONSTR_sizeW(0,1));
62 SET_HDR(p, I16zh_con_info, CCS_SYSTEM);
63 /* Make sure we mask out the relevant bits */
64 p->payload[0] = (StgClosure *)(StgInt)i;
69 rts_mkInt32 (Capability *cap, HsInt32 i)
71 StgClosure *p = (StgClosure *)allocateLocal(cap,CONSTR_sizeW(0,1));
72 SET_HDR(p, I32zh_con_info, CCS_SYSTEM);
73 p->payload[0] = (StgClosure *)(StgInt)i;
78 rts_mkInt64 (Capability *cap, HsInt64 i)
80 StgClosure *p = (StgClosure *)allocateLocal(cap,CONSTR_sizeW(0,2));
81 SET_HDR(p, I64zh_con_info, CCS_SYSTEM);
82 ASSIGN_Int64((P_)&(p->payload[0]), i);
87 rts_mkWord (Capability *cap, HsWord i)
89 StgClosure *p = (StgClosure *)allocateLocal(cap,CONSTR_sizeW(0,1));
90 SET_HDR(p, Wzh_con_info, CCS_SYSTEM);
91 p->payload[0] = (StgClosure *)(StgWord)i;
96 rts_mkWord8 (Capability *cap, HsWord8 w)
98 /* see rts_mkInt* comments */
99 StgClosure *p = (StgClosure *)allocateLocal(cap,CONSTR_sizeW(0,1));
100 SET_HDR(p, W8zh_con_info, CCS_SYSTEM);
101 p->payload[0] = (StgClosure *)(StgWord)(w & 0xff);
106 rts_mkWord16 (Capability *cap, HsWord16 w)
108 /* see rts_mkInt* comments */
109 StgClosure *p = (StgClosure *)allocateLocal(cap,CONSTR_sizeW(0,1));
110 SET_HDR(p, W16zh_con_info, CCS_SYSTEM);
111 p->payload[0] = (StgClosure *)(StgWord)(w & 0xffff);
116 rts_mkWord32 (Capability *cap, HsWord32 w)
118 /* see rts_mkInt* comments */
119 StgClosure *p = (StgClosure *)allocateLocal(cap,CONSTR_sizeW(0,1));
120 SET_HDR(p, W32zh_con_info, CCS_SYSTEM);
121 p->payload[0] = (StgClosure *)(StgWord)(w & 0xffffffff);
126 rts_mkWord64 (Capability *cap, HsWord64 w)
128 StgClosure *p = (StgClosure *)allocateLocal(cap,CONSTR_sizeW(0,2));
129 /* see mk_Int8 comment */
130 SET_HDR(p, W64zh_con_info, CCS_SYSTEM);
131 ASSIGN_Word64((P_)&(p->payload[0]), w);
137 rts_mkFloat (Capability *cap, HsFloat f)
139 StgClosure *p = (StgClosure *)allocateLocal(cap,CONSTR_sizeW(0,1));
140 SET_HDR(p, Fzh_con_info, CCS_SYSTEM);
141 ASSIGN_FLT((P_)p->payload, (StgFloat)f);
146 rts_mkDouble (Capability *cap, HsDouble d)
148 StgClosure *p = (StgClosure *)allocateLocal(cap,CONSTR_sizeW(0,sizeofW(StgDouble)));
149 SET_HDR(p, Dzh_con_info, CCS_SYSTEM);
150 ASSIGN_DBL((P_)p->payload, (StgDouble)d);
155 rts_mkStablePtr (Capability *cap, HsStablePtr s)
157 StgClosure *p = (StgClosure *)allocateLocal(cap,sizeofW(StgHeader)+1);
158 SET_HDR(p, StablePtr_con_info, CCS_SYSTEM);
159 p->payload[0] = (StgClosure *)s;
164 rts_mkPtr (Capability *cap, HsPtr a)
166 StgClosure *p = (StgClosure *)allocateLocal(cap,sizeofW(StgHeader)+1);
167 SET_HDR(p, Ptr_con_info, CCS_SYSTEM);
168 p->payload[0] = (StgClosure *)a;
173 rts_mkFunPtr (Capability *cap, HsFunPtr a)
175 StgClosure *p = (StgClosure *)allocateLocal(cap,sizeofW(StgHeader)+1);
176 SET_HDR(p, FunPtr_con_info, CCS_SYSTEM);
177 p->payload[0] = (StgClosure *)a;
182 rts_mkBool (Capability *cap STG_UNUSED, HsBool b)
185 return (StgClosure *)True_closure;
187 return (StgClosure *)False_closure;
192 rts_mkString (Capability *cap, char *s)
194 return rts_apply(cap, (StgClosure *)unpackCString_closure, rts_mkPtr(cap,s));
198 rts_apply (Capability *cap, HaskellObj f, HaskellObj arg)
202 ap = (StgThunk *)allocateLocal(cap,sizeofW(StgThunk) + 2);
203 SET_HDR(ap, (StgInfoTable *)&stg_ap_2_upd_info, CCS_SYSTEM);
205 ap->payload[1] = arg;
206 return (StgClosure *)ap;
209 /* ----------------------------------------------------------------------------
210 Deconstructing Haskell objects
212 We would like to assert that we have the right kind of object in
213 each case, but this is problematic because in GHCi the info table
214 for the D# constructor (say) might be dynamically loaded. Hence we
215 omit these assertions for now.
216 ------------------------------------------------------------------------- */
219 rts_getChar (HaskellObj p)
221 // See comment above:
222 // ASSERT(p->header.info == Czh_con_info ||
223 // p->header.info == Czh_static_info);
224 return (StgChar)(StgWord)(UNTAG_CLOSURE(p)->payload[0]);
228 rts_getInt (HaskellObj p)
230 // See comment above:
231 // ASSERT(p->header.info == Izh_con_info ||
232 // p->header.info == Izh_static_info);
233 return (HsInt)(UNTAG_CLOSURE(p)->payload[0]);
237 rts_getInt8 (HaskellObj p)
239 // See comment above:
240 // ASSERT(p->header.info == I8zh_con_info ||
241 // p->header.info == I8zh_static_info);
242 return (HsInt8)(HsInt)(UNTAG_CLOSURE(p)->payload[0]);
246 rts_getInt16 (HaskellObj p)
248 // See comment above:
249 // ASSERT(p->header.info == I16zh_con_info ||
250 // p->header.info == I16zh_static_info);
251 return (HsInt16)(HsInt)(UNTAG_CLOSURE(p)->payload[0]);
255 rts_getInt32 (HaskellObj p)
257 // See comment above:
258 // ASSERT(p->header.info == I32zh_con_info ||
259 // p->header.info == I32zh_static_info);
260 return (HsInt32)(HsInt)(UNTAG_CLOSURE(p)->payload[0]);
264 rts_getInt64 (HaskellObj p)
266 // See comment above:
267 // ASSERT(p->header.info == I64zh_con_info ||
268 // p->header.info == I64zh_static_info);
269 return PK_Int64((P_)&(UNTAG_CLOSURE(p)->payload[0]));
273 rts_getWord (HaskellObj p)
275 // See comment above:
276 // ASSERT(p->header.info == Wzh_con_info ||
277 // p->header.info == Wzh_static_info);
278 return (HsWord)(UNTAG_CLOSURE(p)->payload[0]);
282 rts_getWord8 (HaskellObj p)
284 // See comment above:
285 // ASSERT(p->header.info == W8zh_con_info ||
286 // p->header.info == W8zh_static_info);
287 return (HsWord8)(HsWord)(UNTAG_CLOSURE(p)->payload[0]);
291 rts_getWord16 (HaskellObj p)
293 // See comment above:
294 // ASSERT(p->header.info == W16zh_con_info ||
295 // p->header.info == W16zh_static_info);
296 return (HsWord16)(HsWord)(UNTAG_CLOSURE(p)->payload[0]);
300 rts_getWord32 (HaskellObj p)
302 // See comment above:
303 // ASSERT(p->header.info == W32zh_con_info ||
304 // p->header.info == W32zh_static_info);
305 return (HsWord32)(HsWord)(UNTAG_CLOSURE(p)->payload[0]);
309 rts_getWord64 (HaskellObj p)
311 // See comment above:
312 // ASSERT(p->header.info == W64zh_con_info ||
313 // p->header.info == W64zh_static_info);
314 return PK_Word64((P_)&(UNTAG_CLOSURE(p)->payload[0]));
318 rts_getFloat (HaskellObj p)
320 // See comment above:
321 // ASSERT(p->header.info == Fzh_con_info ||
322 // p->header.info == Fzh_static_info);
323 return (float)(PK_FLT((P_)UNTAG_CLOSURE(p)->payload));
327 rts_getDouble (HaskellObj p)
329 // See comment above:
330 // ASSERT(p->header.info == Dzh_con_info ||
331 // p->header.info == Dzh_static_info);
332 return (double)(PK_DBL((P_)UNTAG_CLOSURE(p)->payload));
336 rts_getStablePtr (HaskellObj p)
338 // See comment above:
339 // ASSERT(p->header.info == StablePtr_con_info ||
340 // p->header.info == StablePtr_static_info);
341 return (StgStablePtr)(UNTAG_CLOSURE(p)->payload[0]);
345 rts_getPtr (HaskellObj p)
347 // See comment above:
348 // ASSERT(p->header.info == Ptr_con_info ||
349 // p->header.info == Ptr_static_info);
350 return (Capability *)(UNTAG_CLOSURE(p)->payload[0]);
354 rts_getFunPtr (HaskellObj p)
356 // See comment above:
357 // ASSERT(p->header.info == FunPtr_con_info ||
358 // p->header.info == FunPtr_static_info);
359 return (void *)(UNTAG_CLOSURE(p)->payload[0]);
363 rts_getBool (HaskellObj p)
367 info = get_itbl((StgClosure *)UNTAG_CLOSURE(p));
368 if (info->srt_bitmap == 0) { // srt_bitmap is the constructor tag
375 /* -----------------------------------------------------------------------------
377 -------------------------------------------------------------------------- */
379 INLINE_HEADER void pushClosure (StgTSO *tso, StgWord c) {
385 createGenThread (Capability *cap, nat stack_size, StgClosure *closure)
388 t = createThread (cap, stack_size);
389 pushClosure(t, (W_)closure);
390 pushClosure(t, (W_)&stg_enter_info);
395 createIOThread (Capability *cap, nat stack_size, StgClosure *closure)
398 t = createThread (cap, stack_size);
399 pushClosure(t, (W_)&stg_noforceIO_info);
400 pushClosure(t, (W_)&stg_ap_v_info);
401 pushClosure(t, (W_)closure);
402 pushClosure(t, (W_)&stg_enter_info);
407 * Same as above, but also evaluate the result of the IO action
408 * to whnf while we're at it.
412 createStrictIOThread(Capability *cap, nat stack_size, StgClosure *closure)
415 t = createThread(cap, stack_size);
416 pushClosure(t, (W_)&stg_forceIO_info);
417 pushClosure(t, (W_)&stg_ap_v_info);
418 pushClosure(t, (W_)closure);
419 pushClosure(t, (W_)&stg_enter_info);
423 /* ----------------------------------------------------------------------------
424 Evaluating Haskell expressions
425 ------------------------------------------------------------------------- */
428 rts_eval (Capability *cap, HaskellObj p, /*out*/HaskellObj *ret)
432 tso = createGenThread(cap, RtsFlags.GcFlags.initialStkSize, p);
433 return scheduleWaitThread(tso,ret,cap);
437 rts_eval_ (Capability *cap, HaskellObj p, unsigned int stack_size,
438 /*out*/HaskellObj *ret)
442 tso = createGenThread(cap, stack_size, p);
443 return scheduleWaitThread(tso,ret,cap);
447 * rts_evalIO() evaluates a value of the form (IO a), forcing the action's
448 * result to WHNF before returning.
451 rts_evalIO (Capability *cap, HaskellObj p, /*out*/HaskellObj *ret)
455 tso = createStrictIOThread(cap, RtsFlags.GcFlags.initialStkSize, p);
456 return scheduleWaitThread(tso,ret,cap);
460 * rts_evalStableIO() is suitable for calling from Haskell. It
461 * evaluates a value of the form (StablePtr (IO a)), forcing the
462 * action's result to WHNF before returning. The result is returned
466 rts_evalStableIO (Capability *cap, HsStablePtr s, /*out*/HsStablePtr *ret)
470 SchedulerStatus stat;
472 p = (StgClosure *)deRefStablePtr(s);
473 tso = createStrictIOThread(cap, RtsFlags.GcFlags.initialStkSize, p);
474 // async exceptions are always blocked by default in the created
475 // thread. See #1048.
476 tso->flags |= TSO_BLOCKEX | TSO_INTERRUPTIBLE;
477 cap = scheduleWaitThread(tso,&r,cap);
478 stat = rts_getSchedStatus(cap);
480 if (stat == Success && ret != NULL) {
482 *ret = getStablePtr((StgPtr)r);
489 * Like rts_evalIO(), but doesn't force the action's result.
492 rts_evalLazyIO (Capability *cap, HaskellObj p, /*out*/HaskellObj *ret)
496 tso = createIOThread(cap, RtsFlags.GcFlags.initialStkSize, p);
497 return scheduleWaitThread(tso,ret,cap);
501 rts_evalLazyIO_ (Capability *cap, HaskellObj p, unsigned int stack_size,
502 /*out*/HaskellObj *ret)
506 tso = createIOThread(cap, stack_size, p);
507 return scheduleWaitThread(tso,ret,cap);
510 /* Convenience function for decoding the returned status. */
513 rts_checkSchedStatus (char* site, Capability *cap)
515 SchedulerStatus rc = cap->running_task->stat;
520 errorBelch("%s: uncaught exception",site);
521 stg_exit(EXIT_FAILURE);
523 errorBelch("%s: interrupted", site);
524 stg_exit(EXIT_FAILURE);
526 errorBelch("%s: Return code (%d) not ok",(site),(rc));
527 stg_exit(EXIT_FAILURE);
532 rts_getSchedStatus (Capability *cap)
534 return cap->running_task->stat;
543 task = newBoundTask();
546 waitForReturnCapability(&cap, task);
547 return (Capability *)cap;
550 // Exiting the RTS: we hold a Capability that is not necessarily the
551 // same one that was originally returned by rts_lock(), because
552 // rts_evalIO() etc. may return a new one. Now that we have
553 // investigated the return value, we can release the Capability,
554 // and free the Task (in that order).
557 rts_unlock (Capability *cap)
561 task = cap->running_task;
562 ASSERT_FULL_CAPABILITY_INVARIANTS(cap,task);
564 // Now release the Capability. With the capability released, GC
565 // may happen. NB. does not try to put the current Task on the
567 // NB. keep cap->lock held while we call boundTaskExiting(). This
568 // is necessary during shutdown, where we want the invariant that
569 // after shutdownCapability(), all the Tasks associated with the
570 // Capability have completed their shutdown too. Otherwise we
571 // could have boundTaskExiting()/workerTaskStop() running at some
572 // random point in the future, which causes problems for
573 // freeTaskManager().
574 ACQUIRE_LOCK(&cap->lock);
575 releaseCapability_(cap,rtsFalse);
577 // Finally, we can release the Task to the free list.
578 boundTaskExiting(task);
579 RELEASE_LOCK(&cap->lock);