n = R1;
payload_words = ROUNDUP_BYTES_TO_WDS(n);
words = BYTES_TO_WDS(SIZEOF_StgArrWords) + payload_words;
- "ptr" p = foreign "C" allocate(words);
+ "ptr" p = foreign "C" allocateLocal(BaseReg "ptr",words);
TICK_ALLOC_PRIM(SIZEOF_StgArrWords,WDS(payload_words),0);
SET_HDR(p, stg_ARR_WORDS_info, W_[CCCS]);
StgArrWords_words(p) = payload_words;
MAYBE_GC(R2_PTR,newArrayzh_fast);
words = BYTES_TO_WDS(SIZEOF_StgMutArrPtrs) + n;
- "ptr" arr = foreign "C" allocate(words);
+ "ptr" arr = foreign "C" allocateLocal(BaseReg "ptr",words);
TICK_ALLOC_PRIM(SIZEOF_StgMutArrPtrs, WDS(n), 0);
SET_HDR(arr, stg_MUT_ARR_PTRS_info, W_[CCCS]);
/* ToDo: this is shockingly inefficient */
+#ifndef SMP
section "bss" {
mp_tmp1:
bits8 [SIZEOF_MP_INT];
}
section "bss" {
- result1:
+ mp_result1:
bits8 [SIZEOF_MP_INT];
}
section "bss" {
- result2:
+ mp_result2:
bits8 [SIZEOF_MP_INT];
}
+#endif
-#define GMP_TAKE2_RET1(name,mp_fun) \
-name \
-{ \
- CInt s1, s2; \
- W_ d1, d2; \
- \
- /* call doYouWantToGC() */ \
- MAYBE_GC(R2_PTR & R4_PTR, name); \
- \
- s1 = W_TO_INT(R1); \
- d1 = R2; \
- s2 = W_TO_INT(R3); \
- d2 = R4; \
- \
- MP_INT__mp_alloc(mp_tmp1) = W_TO_INT(StgArrWords_words(d1)); \
- MP_INT__mp_size(mp_tmp1) = (s1); \
- MP_INT__mp_d(mp_tmp1) = BYTE_ARR_CTS(d1); \
- MP_INT__mp_alloc(mp_tmp2) = W_TO_INT(StgArrWords_words(d2)); \
- MP_INT__mp_size(mp_tmp2) = (s2); \
- MP_INT__mp_d(mp_tmp2) = BYTE_ARR_CTS(d2); \
- \
- foreign "C" mpz_init(result1); \
- \
- /* Perform the operation */ \
- foreign "C" mp_fun(result1,mp_tmp1,mp_tmp2); \
- \
- RET_NP(TO_W_(MP_INT__mp_size(result1)), \
- MP_INT__mp_d(result1) - SIZEOF_StgArrWords); \
-}
-
-#define GMP_TAKE1_RET1(name,mp_fun) \
-name \
-{ \
- CInt s1; \
- W_ d1; \
- \
- /* call doYouWantToGC() */ \
- MAYBE_GC(R2_PTR, name); \
- \
- d1 = R2; \
- s1 = W_TO_INT(R1); \
- \
- MP_INT__mp_alloc(mp_tmp1) = W_TO_INT(StgArrWords_words(d1)); \
- MP_INT__mp_size(mp_tmp1) = (s1); \
- MP_INT__mp_d(mp_tmp1) = BYTE_ARR_CTS(d1); \
- \
- foreign "C" mpz_init(result1); \
- \
- /* Perform the operation */ \
- foreign "C" mp_fun(result1,mp_tmp1); \
- \
- RET_NP(TO_W_(MP_INT__mp_size(result1)), \
- MP_INT__mp_d(result1) - SIZEOF_StgArrWords); \
-}
+#ifdef SMP
+#define FETCH_MP_TEMP(X) \
+W_ X; \
+X = BaseReg + (OFFSET_StgRegTable_r ## X);
+#else
+#define FETCH_MP_TEMP(X) /* Nothing */
+#endif
-#define GMP_TAKE2_RET2(name,mp_fun) \
-name \
-{ \
- CInt s1, s2; \
- W_ d1, d2; \
- \
- /* call doYouWantToGC() */ \
- MAYBE_GC(R2_PTR & R4_PTR, name); \
- \
- s1 = W_TO_INT(R1); \
- d1 = R2; \
- s2 = W_TO_INT(R3); \
- d2 = R4; \
- \
- MP_INT__mp_alloc(mp_tmp1) = W_TO_INT(StgArrWords_words(d1)); \
- MP_INT__mp_size(mp_tmp1) = (s1); \
- MP_INT__mp_d(mp_tmp1) = BYTE_ARR_CTS(d1); \
- MP_INT__mp_alloc(mp_tmp2) = W_TO_INT(StgArrWords_words(d2)); \
- MP_INT__mp_size(mp_tmp2) = (s2); \
- MP_INT__mp_d(mp_tmp2) = BYTE_ARR_CTS(d2); \
- \
- foreign "C" mpz_init(result1); \
- foreign "C" mpz_init(result2); \
- \
- /* Perform the operation */ \
- foreign "C" mp_fun(result1,result2,mp_tmp1,mp_tmp2); \
- \
- RET_NPNP(TO_W_(MP_INT__mp_size(result1)), \
- MP_INT__mp_d(result1) - SIZEOF_StgArrWords, \
- TO_W_(MP_INT__mp_size(result2)), \
- MP_INT__mp_d(result2) - SIZEOF_StgArrWords); \
+#define GMP_TAKE2_RET1(name,mp_fun) \
+name \
+{ \
+ CInt s1, s2; \
+ W_ d1, d2; \
+ FETCH_MP_TEMP(mp_tmp1); \
+ FETCH_MP_TEMP(mp_tmp2); \
+ FETCH_MP_TEMP(mp_result1) \
+ FETCH_MP_TEMP(mp_result2); \
+ \
+ /* call doYouWantToGC() */ \
+ MAYBE_GC(R2_PTR & R4_PTR, name); \
+ \
+ s1 = W_TO_INT(R1); \
+ d1 = R2; \
+ s2 = W_TO_INT(R3); \
+ d2 = R4; \
+ \
+ MP_INT__mp_alloc(mp_tmp1) = W_TO_INT(StgArrWords_words(d1)); \
+ MP_INT__mp_size(mp_tmp1) = (s1); \
+ MP_INT__mp_d(mp_tmp1) = BYTE_ARR_CTS(d1); \
+ MP_INT__mp_alloc(mp_tmp2) = W_TO_INT(StgArrWords_words(d2)); \
+ MP_INT__mp_size(mp_tmp2) = (s2); \
+ MP_INT__mp_d(mp_tmp2) = BYTE_ARR_CTS(d2); \
+ \
+ foreign "C" mpz_init(mp_result1 "ptr"); \
+ \
+ /* Perform the operation */ \
+ foreign "C" mp_fun(mp_result1 "ptr",mp_tmp1 "ptr",mp_tmp2 "ptr"); \
+ \
+ RET_NP(TO_W_(MP_INT__mp_size(mp_result1)), \
+ MP_INT__mp_d(mp_result1) - SIZEOF_StgArrWords); \
+}
+
+#define GMP_TAKE1_RET1(name,mp_fun) \
+name \
+{ \
+ CInt s1; \
+ W_ d1; \
+ FETCH_MP_TEMP(mp_tmp1); \
+ FETCH_MP_TEMP(mp_result1) \
+ \
+ /* call doYouWantToGC() */ \
+ MAYBE_GC(R2_PTR, name); \
+ \
+ d1 = R2; \
+ s1 = W_TO_INT(R1); \
+ \
+ MP_INT__mp_alloc(mp_tmp1) = W_TO_INT(StgArrWords_words(d1)); \
+ MP_INT__mp_size(mp_tmp1) = (s1); \
+ MP_INT__mp_d(mp_tmp1) = BYTE_ARR_CTS(d1); \
+ \
+ foreign "C" mpz_init(mp_result1 "ptr"); \
+ \
+ /* Perform the operation */ \
+ foreign "C" mp_fun(mp_result1 "ptr",mp_tmp1 "ptr"); \
+ \
+ RET_NP(TO_W_(MP_INT__mp_size(mp_result1)), \
+ MP_INT__mp_d(mp_result1) - SIZEOF_StgArrWords); \
+}
+
+#define GMP_TAKE2_RET2(name,mp_fun) \
+name \
+{ \
+ CInt s1, s2; \
+ W_ d1, d2; \
+ FETCH_MP_TEMP(mp_tmp1); \
+ FETCH_MP_TEMP(mp_tmp2); \
+ FETCH_MP_TEMP(mp_result1) \
+ FETCH_MP_TEMP(mp_result2) \
+ \
+ /* call doYouWantToGC() */ \
+ MAYBE_GC(R2_PTR & R4_PTR, name); \
+ \
+ s1 = W_TO_INT(R1); \
+ d1 = R2; \
+ s2 = W_TO_INT(R3); \
+ d2 = R4; \
+ \
+ MP_INT__mp_alloc(mp_tmp1) = W_TO_INT(StgArrWords_words(d1)); \
+ MP_INT__mp_size(mp_tmp1) = (s1); \
+ MP_INT__mp_d(mp_tmp1) = BYTE_ARR_CTS(d1); \
+ MP_INT__mp_alloc(mp_tmp2) = W_TO_INT(StgArrWords_words(d2)); \
+ MP_INT__mp_size(mp_tmp2) = (s2); \
+ MP_INT__mp_d(mp_tmp2) = BYTE_ARR_CTS(d2); \
+ \
+ foreign "C" mpz_init(mp_result1 "ptr"); \
+ foreign "C" mpz_init(mp_result2 "ptr"); \
+ \
+ /* Perform the operation */ \
+ foreign "C" mp_fun(mp_result1 "ptr",mp_result2 "ptr",mp_tmp1 "ptr",mp_tmp2 "ptr"); \
+ \
+ RET_NPNP(TO_W_(MP_INT__mp_size(mp_result1)), \
+ MP_INT__mp_d(mp_result1) - SIZEOF_StgArrWords, \
+ TO_W_(MP_INT__mp_size(mp_result2)), \
+ MP_INT__mp_d(mp_result2) - SIZEOF_StgArrWords); \
}
GMP_TAKE2_RET1(plusIntegerzh_fast, mpz_add)
GMP_TAKE2_RET2(quotRemIntegerzh_fast, mpz_tdiv_qr)
GMP_TAKE2_RET2(divModIntegerzh_fast, mpz_fdiv_qr)
+#ifndef SMP
section "bss" {
- aa: W_; // NB. aa is really an mp_limb_t
+ mp_tmp_w: W_; // NB. mp_tmp_w is really an here mp_limb_t
}
+#endif
gcdIntzh_fast
{
/* R1 = the first Int#; R2 = the second Int# */
W_ r;
+ FETCH_MP_TEMP(mp_tmp_w);
- W_[aa] = R1;
- r = foreign "C" mpn_gcd_1(aa, 1, R2);
+ W_[mp_tmp_w] = R1;
+ r = foreign "C" mpn_gcd_1(mp_tmp_w "ptr", 1, R2);
R1 = r;
/* Result parked in R1, return via info-pointer at TOS */
jump %ENTRY_CODE(Sp(0));
}
-section "bss" {
- exponent: W_;
-}
-
decodeFloatzh_fast
{
W_ p;
F_ arg;
+ FETCH_MP_TEMP(mp_tmp1);
+ FETCH_MP_TEMP(mp_tmp_w);
/* arguments: F1 = Float# */
arg = F1;
MP_INT__mp_d(mp_tmp1) = BYTE_ARR_CTS(p);
/* Perform the operation */
- foreign "C" __decodeFloat(mp_tmp1,exponent,arg);
+ foreign "C" __decodeFloat(mp_tmp1 "ptr",mp_tmp_w "ptr" ,arg);
/* returns: (Int# (expn), Int#, ByteArray#) */
- RET_NNP(W_[exponent], TO_W_(MP_INT__mp_size(mp_tmp1)), p);
+ RET_NNP(W_[mp_tmp_w], TO_W_(MP_INT__mp_size(mp_tmp1)), p);
}
#define DOUBLE_MANTISSA_SIZE SIZEOF_DOUBLE
{
D_ arg;
W_ p;
+ FETCH_MP_TEMP(mp_tmp1);
+ FETCH_MP_TEMP(mp_tmp_w);
/* arguments: D1 = Double# */
arg = D1;
MP_INT__mp_d(mp_tmp1) = BYTE_ARR_CTS(p);
/* Perform the operation */
- foreign "C" __decodeDouble(mp_tmp1,exponent,arg);
+ foreign "C" __decodeDouble(mp_tmp1 "ptr", mp_tmp_w "ptr",arg);
/* returns: (Int# (expn), Int#, ByteArray#) */
- RET_NNP(W_[exponent], TO_W_(MP_INT__mp_size(mp_tmp1)), p);
+ RET_NNP(W_[mp_tmp_w], TO_W_(MP_INT__mp_size(mp_tmp1)), p);
}
/* -----------------------------------------------------------------------------
frame = Sp;
trec = StgTSO_trec(CurrentTSO);
"ptr" outer = foreign "C" stmGetEnclosingTRec(trec "ptr");
- r = foreign "C" stmCommitTransaction(trec "ptr");
+ r = foreign "C" stmCommitNestedTransaction(BaseReg "ptr", trec "ptr");
if (r) {
/* Succeeded (either first branch or second branch) */
StgTSO_trec(CurrentTSO) = outer;
} else {
/* Did not commit: retry */
W_ new_trec;
- "ptr" new_trec = foreign "C" stmStartTransaction(outer "ptr");
+ "ptr" new_trec = foreign "C" stmStartTransaction(BaseReg "ptr", outer "ptr");
StgTSO_trec(CurrentTSO) = new_trec;
if (StgCatchRetryFrame_running_alt_code(frame)) {
R1 = StgCatchRetryFrame_alt_code(frame);
jump stg_block_noregs;
} else {
/* Previous attempt is no longer valid: try again */
- "ptr" trec = foreign "C" stmStartTransaction(NO_TREC "ptr");
+ "ptr" trec = foreign "C" stmStartTransaction(BaseReg "ptr", NO_TREC "ptr");
StgTSO_trec(CurrentTSO) = trec;
StgAtomicallyFrame_waiting(frame) = 0 :: CInt; /* false; */
R1 = StgAtomicallyFrame_code(frame);
}
} else {
/* The TSO is not currently waiting: try to commit the transaction */
- valid = foreign "C" stmCommitTransaction(trec "ptr");
+ valid = foreign "C" stmCommitTransaction(BaseReg "ptr", trec "ptr");
if (valid) {
/* Transaction was valid: commit succeeded */
StgTSO_trec(CurrentTSO) = NO_TREC;
jump %ENTRY_CODE(Sp(SP_OFF));
} else {
/* Transaction was not valid: try again */
- "ptr" trec = foreign "C" stmStartTransaction(NO_TREC "ptr");
+ "ptr" trec = foreign "C" stmStartTransaction(BaseReg "ptr", NO_TREC "ptr");
StgTSO_trec(CurrentTSO) = trec;
R1 = StgAtomicallyFrame_code(frame);
Sp_adj(-1);
W_ old_trec;
W_ new_trec;
+ // stmStartTransaction may allocate
+ MAYBE_GC (R1_PTR, atomicallyzh_fast);
+
/* Args: R1 = m :: STM a */
STK_CHK_GEN(SIZEOF_StgAtomicallyFrame + WDS(1), R1_PTR, atomicallyzh_fast);
/* Start the memory transcation */
old_trec = StgTSO_trec(CurrentTSO);
- "ptr" new_trec = foreign "C" stmStartTransaction(old_trec "ptr");
+ ASSERT(old_trec == NO_TREC);
+ "ptr" new_trec = foreign "C" stmStartTransaction(BaseReg "ptr", old_trec "ptr");
StgTSO_trec(CurrentTSO) = new_trec;
/* Apply R1 to the realworld token */
W_ new_trec;
W_ trec;
+ // stmStartTransaction may allocate
+ MAYBE_GC (R1_PTR & R2_PTR, catchRetryzh_fast);
+
/* Args: R1 :: STM a */
/* Args: R2 :: STM a */
STK_CHK_GEN(SIZEOF_StgCatchRetryFrame + WDS(1), R1_PTR & R2_PTR, catchRetryzh_fast);
/* Start a nested transaction within which to run the first code */
trec = StgTSO_trec(CurrentTSO);
- "ptr" new_trec = foreign "C" stmStartTransaction(trec "ptr");
+ "ptr" new_trec = foreign "C" stmStartTransaction(BaseReg "ptr", trec "ptr");
StgTSO_trec(CurrentTSO) = new_trec;
/* Set up the catch-retry frame */
ASSERT(outer != NO_TREC);
if (!StgCatchRetryFrame_running_alt_code(frame)) {
// Retry in the first code: try the alternative
- "ptr" trec = foreign "C" stmStartTransaction(outer "ptr");
+ "ptr" trec = foreign "C" stmStartTransaction(BaseReg "ptr", outer "ptr");
StgTSO_trec(CurrentTSO) = trec;
StgCatchRetryFrame_running_alt_code(frame) = 1 :: CInt; // true;
R1 = StgCatchRetryFrame_alt_code(frame);
// Retry in the alternative code: propagate
W_ other_trec;
other_trec = StgCatchRetryFrame_first_code_trec(frame);
- r = foreign "C" stmMergeForWaiting(trec "ptr", other_trec "ptr");
+ r = foreign "C" stmCommitNestedTransaction(BaseReg "ptr", other_trec "ptr");
if (r) {
- r = foreign "C" stmCommitTransaction(trec "ptr");
+ r = foreign "C" stmCommitNestedTransaction(BaseReg "ptr", trec "ptr");
}
if (r) {
// Merge between siblings succeeded: commit it back to enclosing transaction
goto retry_pop_stack;
} else {
// Merge failed: we musn't propagate the retry. Try both paths again.
- "ptr" trec = foreign "C" stmStartTransaction(outer "ptr");
+ "ptr" trec = foreign "C" stmStartTransaction(BaseReg "ptr", outer "ptr");
StgCatchRetryFrame_first_code_trec(frame) = trec;
StgCatchRetryFrame_running_alt_code(frame) = 0 :: CInt; // false;
StgTSO_trec(CurrentTSO) = trec;
// We've reached the ATOMICALLY_FRAME: attempt to wait
ASSERT(frame_type == ATOMICALLY_FRAME);
ASSERT(outer == NO_TREC);
- r = foreign "C" stmWait(CurrentTSO "ptr", trec "ptr");
+ r = foreign "C" stmWait(BaseReg "ptr", CurrentTSO "ptr", trec "ptr");
if (r) {
// Transaction was valid: stmWait put us on the TVars' queues, we now block
StgAtomicallyFrame_waiting(frame) = 1 :: CInt; // true
jump stg_block_noregs;
} else {
// Transaction was not valid: retry immediately
- "ptr" trec = foreign "C" stmStartTransaction(outer "ptr");
+ "ptr" trec = foreign "C" stmStartTransaction(BaseReg "ptr", outer "ptr");
StgTSO_trec(CurrentTSO) = trec;
R1 = StgAtomicallyFrame_code(frame);
Sp = frame;
newTVarzh_fast
{
W_ tv;
+ W_ new_value;
/* Args: R1 = initialisation value */
- ALLOC_PRIM( SIZEOF_StgTVar, R1_PTR, newTVarzh_fast);
- tv = Hp - SIZEOF_StgTVar + WDS(1);
- SET_HDR(tv,stg_TVAR_info,W_[CCCS]);
- StgTVar_current_value(tv) = R1;
- StgTVar_first_wait_queue_entry(tv) = stg_END_STM_WAIT_QUEUE_closure;
-
+ MAYBE_GC (R1_PTR, newTVarzh_fast);
+ new_value = R1;
+ tv = foreign "C" stmNewTVar(BaseReg "ptr", new_value "ptr");
RET_P(tv);
}
MAYBE_GC (R1_PTR, readTVarzh_fast); // Call to stmReadTVar may allocate
trec = StgTSO_trec(CurrentTSO);
tvar = R1;
- "ptr" result = foreign "C" stmReadTVar(trec "ptr", tvar "ptr");
+ "ptr" result = foreign "C" stmReadTVar(BaseReg "ptr", trec "ptr", tvar "ptr");
RET_P(result);
}
trec = StgTSO_trec(CurrentTSO);
tvar = R1;
new_value = R2;
- foreign "C" stmWriteTVar(trec "ptr", tvar "ptr", new_value "ptr");
+ foreign "C" stmWriteTVar(BaseReg "ptr", trec "ptr", tvar "ptr", new_value "ptr");
jump %ENTRY_CODE(Sp(0));
}
StgTSO_sp(tso) = StgTSO_sp(tso) + WDS(3); \
lval = W_[StgTSO_sp(tso) - WDS(1)];
-
takeMVarzh_fast
{
W_ mvar, val, info, tso;
-#if defined(SMP)
- foreign "C" ACQUIRE_LOCK(sm_mutex "ptr");
-#endif
-
/* args: R1 = MVar closure */
mvar = R1;
+#if defined(SMP)
+ "ptr" info = foreign "C" lockClosure(mvar "ptr");
+#else
info = GET_INFO(mvar);
+#endif
/* If the MVar is empty, put ourselves on its blocking queue,
* and wait until we're woken up.
StgTSO_block_info(CurrentTSO) = mvar;
StgMVar_tail(mvar) = CurrentTSO;
-#if defined(SMP)
- foreign "C" RELEASE_LOCK(sm_mutex "ptr");
-#endif
-
jump stg_block_takemvar;
}
"ptr" tso = foreign "C" unblockOne(StgMVar_head(mvar) "ptr");
StgMVar_head(mvar) = tso;
#endif
+
if (StgMVar_head(mvar) == stg_END_TSO_QUEUE_closure) {
StgMVar_tail(mvar) = stg_END_TSO_QUEUE_closure;
}
#if defined(SMP)
- foreign "C" RELEASE_LOCK(sm_mutex "ptr");
+ foreign "C" unlockClosure(mvar "ptr", stg_FULL_MVAR_info);
#endif
-
RET_P(val);
}
else
{
/* No further putMVars, MVar is now empty */
-
- /* do this last... we might have locked the MVar in the SMP case,
- * and writing the info pointer will unlock it.
- */
- SET_INFO(mvar,stg_EMPTY_MVAR_info);
StgMVar_value(mvar) = stg_END_TSO_QUEUE_closure;
-
+
#if defined(SMP)
- foreign "C" RELEASE_LOCK(sm_mutex "ptr");
+ foreign "C" unlockClosure(mvar "ptr", stg_EMPTY_MVAR_info);
+#else
+ SET_INFO(mvar,stg_EMPTY_MVAR_info);
#endif
RET_P(val);
{
W_ mvar, val, info, tso;
-#if defined(SMP)
- foreign "C" ACQUIRE_LOCK(sm_mutex "ptr");
-#endif
-
/* args: R1 = MVar closure */
mvar = R1;
+#if defined(SMP)
+ "ptr" info = foreign "C" lockClosure(mvar "ptr");
+#else
info = GET_INFO(mvar);
+#endif
if (info == stg_EMPTY_MVAR_info) {
+#if defined(SMP)
+ foreign "C" unlockClosure(mvar "ptr", stg_EMPTY_MVAR_info);
+#endif
/* HACK: we need a pointer to pass back,
* so we abuse NO_FINALIZER_closure
*/
-#if defined(SMP)
- foreign "C" RELEASE_LOCK(sm_mutex "ptr");
-#endif
RET_NP(0, stg_NO_FINALIZER_closure);
}
val = StgMVar_value(mvar);
if (StgMVar_head(mvar) != stg_END_TSO_QUEUE_closure) {
+
/* There are putMVar(s) waiting...
* wake up the first thread on the queue
*/
if (StgMVar_head(mvar) == stg_END_TSO_QUEUE_closure) {
StgMVar_tail(mvar) = stg_END_TSO_QUEUE_closure;
}
+#if defined(SMP)
+ foreign "C" unlockClosure(mvar "ptr", stg_FULL_MVAR_info);
+#endif
}
else
{
/* No further putMVars, MVar is now empty */
StgMVar_value(mvar) = stg_END_TSO_QUEUE_closure;
+#if defined(SMP)
+ foreign "C" unlockClosure(mvar "ptr", stg_EMPTY_MVAR_info);
+#else
SET_INFO(mvar,stg_EMPTY_MVAR_info);
+#endif
}
-#if defined(SMP)
- foreign "C" RELEASE_LOCK(sm_mutex "ptr");
-#endif
-
RET_NP(1, val);
}
{
W_ mvar, info, tso;
-#if defined(SMP)
- foreign "C" ACQUIRE_LOCK(sm_mutex "ptr");
-#endif
-
/* args: R1 = MVar, R2 = value */
mvar = R1;
+#if defined(SMP)
+ "ptr" info = foreign "C" lockClosure(mvar "ptr");
+#else
info = GET_INFO(mvar);
+#endif
if (info == stg_FULL_MVAR_info) {
if (StgMVar_head(mvar) == stg_END_TSO_QUEUE_closure) {
StgTSO_block_info(CurrentTSO) = mvar;
StgMVar_tail(mvar) = CurrentTSO;
-#if defined(SMP)
- foreign "C" RELEASE_LOCK(sm_mutex "ptr");
-#endif
jump stg_block_putmvar;
}
if (StgMVar_head(mvar) != stg_END_TSO_QUEUE_closure) {
+
/* There are takeMVar(s) waiting: wake up the first one
*/
ASSERT(StgTSO_why_blocked(StgMVar_head(mvar)) == BlockedOnMVar::I16);
}
#if defined(SMP)
- foreign "C" RELEASE_LOCK(sm_mutex "ptr");
+ foreign "C" unlockClosure(mvar "ptr", stg_EMPTY_MVAR_info);
#endif
jump %ENTRY_CODE(Sp(0));
}
{
/* No further takes, the MVar is now full. */
StgMVar_value(mvar) = R2;
- /* unlocks the MVar in the SMP case */
- SET_INFO(mvar,stg_FULL_MVAR_info);
#if defined(SMP)
- foreign "C" RELEASE_LOCK(sm_mutex "ptr");
+ foreign "C" unlockClosure(mvar "ptr", stg_FULL_MVAR_info);
+#else
+ SET_INFO(mvar,stg_FULL_MVAR_info);
#endif
jump %ENTRY_CODE(Sp(0));
}
{
W_ mvar, info, tso;
-#if defined(SMP)
- foreign "C" ACQUIRE_LOCK(sm_mutex "ptr");
-#endif
-
/* args: R1 = MVar, R2 = value */
mvar = R1;
+#if defined(SMP)
+ "ptr" info = foreign "C" lockClosure(mvar "ptr");
+#else
info = GET_INFO(mvar);
+#endif
if (info == stg_FULL_MVAR_info) {
#if defined(SMP)
- foreign "C" RELEASE_LOCK(sm_mutex "ptr");
+ foreign "C" unlockClosure(mvar "ptr", stg_FULL_MVAR_info);
#endif
RET_N(0);
}
if (StgMVar_head(mvar) != stg_END_TSO_QUEUE_closure) {
+
/* There are takeMVar(s) waiting: wake up the first one
*/
ASSERT(StgTSO_why_blocked(StgMVar_head(mvar)) == BlockedOnMVar::I16);
}
#if defined(SMP)
- foreign "C" RELEASE_LOCK(sm_mutex "ptr");
+ foreign "C" unlockClosure(mvar "ptr", stg_EMPTY_MVAR_info);
#endif
jump %ENTRY_CODE(Sp(0));
}
{
/* No further takes, the MVar is now full. */
StgMVar_value(mvar) = R2;
- /* unlocks the MVar in the SMP case */
- SET_INFO(mvar,stg_FULL_MVAR_info);
+
#if defined(SMP)
- foreign "C" RELEASE_LOCK(sm_mutex "ptr");
+ foreign "C" unlockClosure(mvar "ptr", stg_FULL_MVAR_info);
+#else
+ SET_INFO(mvar,stg_FULL_MVAR_info);
#endif
jump %ENTRY_CODE(Sp(0));
}