/* -----------------------------------------------------------------------------
- * $Id: PrimOps.hc,v 1.109 2003/07/12 00:08:28 sof Exp $
+ * $Id: PrimOps.hc,v 1.116 2004/01/08 15:26:44 simonmar Exp $
*
* (c) The GHC Team, 1998-2002
*
#define PUSHED(m) Sp -= (m); JMP_(ENTRY_CODE(Sp[m]));
# define RET_P(a) PUSH(1,a); PUSHED(1)
-# define RET_N(a) PUSH(1,a); PUSHED(2)
+# define RET_N(a) PUSH(1,a); PUSHED(1)
# define RET_PP(a,b) PUSH(2,a); PUSH(1,b); PUSHED(2)
# define RET_NN(a,b) PUSH(2,a); PUSH(1,b); PUSHED(2)
{
FB_
SET_INFO((StgClosure *)R1.cl,&stg_MUT_ARR_PTRS_info);
- recordMutable((StgMutClosure*)R1.cl);
+
+ // SUBTLETY TO DO WITH THE OLD GEN MUTABLE LIST
+ //
+ // A MUT_ARR_PTRS lives on the mutable list, but a MUT_ARR_PTRS_FROZEN
+ // normally doesn't. However, when we freeze a MUT_ARR_PTRS, we leave
+ // it on the mutable list for the GC to remove (removing something from
+ // the mutable list is not easy, because the mut_list is only singly-linked).
+ //
+ // So, when we thaw a MUT_ARR_PTRS_FROZEN, we must cope with two cases:
+ // either it is on a mut_list, or it isn't. We adopt the convention that
+ // the mut_link field is NULL if it isn't on a mut_list, and the GC
+ // maintains this invariant.
+ //
+ if (((StgMutArrPtrs *)R1.cl)->mut_link == NULL) {
+ recordMutable((StgMutClosure*)R1.cl);
+ }
TICK_RET_UNBOXED_TUP(1);
RET_P(R1.p);
FE_
}
-FN_(forkProcesszh_fast)
-{
- pid_t pid;
-
- FB_
- /* args: none */
- /* result: Pid */
-
- R1.i = RET_STGCALL1(StgInt, forkProcess, CurrentTSO);
-
- RET_N(R1.i);
- FE_
-}
-
FN_(yieldzh_fast)
{
FB_
FE_
}
+FN_(isCurrentThreadBoundzh_fast)
+{
+ /* no args */
+ I_ r;
+ FB_
+ r = (I_)(RET_STGCALL1(StgBool, isThreadBound, CurrentTSO));
+ RET_N(r);
+ FE_
+}
/* -----------------------------------------------------------------------------
* MVar primitives
nat target;
#endif
FB_
- /* args: R1.i */
+ /* args: R1.i (microsecond delay amount) */
ASSERT(CurrentTSO->why_blocked == NotBlocked);
CurrentTSO->why_blocked = BlockedOnDelay;
ACQUIRE_LOCK(&sched_mutex);
#ifdef mingw32_TARGET_OS
/* could probably allocate this on the heap instead */
- ares = (StgAsyncIOResult*)RET_STGCALL2(P_,stgMallocBytes,sizeof(StgAsyncIOResult), "asyncWritezh_fast");
+ ares = (StgAsyncIOResult*)RET_STGCALL2(P_,stgMallocBytes,sizeof(StgAsyncIOResult), "delayzh_fast");
reqID = RET_STGCALL1(W_,addDelayRequest,R1.i);
ares->reqID = reqID;
ares->len = 0;
CurrentTSO->why_blocked = BlockedOnDoProc;
APPEND_TO_BLOCKED_QUEUE(CurrentTSO);
#else
- target = (R1.i / (TICK_MILLISECS*1000)) + getourtimeofday();
+ target = ((R1.i + TICK_MILLISECS*1000-1) / (TICK_MILLISECS*1000)) + getourtimeofday();
CurrentTSO->block_info.target = target;
/* Insert the new thread in the sleeping queue. */
FE_
}
#endif
+