X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2FPrimOps.cmm;h=4f6c2526d4ecf6c2c7cb5ab3c8e0ec9562769687;hb=8625c675de45bdb8bcfa795572ce7c47687c147c;hp=d09a856f48593e50a9eec89cad4464587c88e702;hpb=0714abaf0b190439631866132a5bf53c8d3a5d69;p=ghc-hetmet.git diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm index d09a856..4f6c252 100644 --- a/rts/PrimOps.cmm +++ b/rts/PrimOps.cmm @@ -34,7 +34,7 @@ import pthread_mutex_unlock; import base_ControlziExceptionziBase_nestedAtomically_closure; import EnterCriticalSection; import LeaveCriticalSection; -import ghczmprim_GHCziBool_False_closure; +import ghczmprim_GHCziTypes_False_closure; #if !defined(mingw32_HOST_OS) import sm_mutex; #endif @@ -64,7 +64,7 @@ stg_newByteArrayzh ("ptr" p) = foreign "C" allocate(MyCapability() "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; + StgArrWords_bytes(p) = n; RET_P(p); } @@ -73,10 +73,11 @@ stg_newByteArrayzh stg_newPinnedByteArrayzh { - W_ words, bytes, payload_words, p; + W_ words, n, bytes, payload_words, p; MAYBE_GC(NO_PTRS,stg_newPinnedByteArrayzh); - bytes = R1; + n = R1; + bytes = n; /* payload_words is what we will tell the profiler we had to allocate */ payload_words = ROUNDUP_BYTES_TO_WDS(bytes); /* When we actually allocate memory, we need to allow space for the @@ -96,18 +97,25 @@ stg_newPinnedByteArrayzh p = p + ((-p - SIZEOF_StgArrWords) & BA_MASK); SET_HDR(p, stg_ARR_WORDS_info, W_[CCCS]); - StgArrWords_words(p) = payload_words; + StgArrWords_bytes(p) = n; RET_P(p); } stg_newAlignedPinnedByteArrayzh { - W_ words, bytes, payload_words, p, alignment; + W_ words, n, bytes, payload_words, p, alignment; MAYBE_GC(NO_PTRS,stg_newAlignedPinnedByteArrayzh); - bytes = R1; + n = R1; alignment = R2; + /* we always supply at least word-aligned memory, so there's no + need to allow extra space for alignment if the requirement is less + than a word. This also prevents mischief with alignment == 0. */ + if (alignment <= SIZEOF_W) { alignment = 1; } + + bytes = n; + /* payload_words is what we will tell the profiler we had to allocate */ payload_words = ROUNDUP_BYTES_TO_WDS(bytes); @@ -129,7 +137,7 @@ stg_newAlignedPinnedByteArrayzh p = p + ((-p - SIZEOF_StgArrWords) & (alignment - 1)); SET_HDR(p, stg_ARR_WORDS_info, W_[CCCS]); - StgArrWords_words(p) = payload_words; + StgArrWords_bytes(p) = n; RET_P(p); } @@ -378,7 +386,7 @@ stg_mkWeakForeignEnvzh TICK_ALLOC_PRIM(SIZEOF_StgArrWords,WDS(payload_words),0); SET_HDR(p, stg_ARR_WORDS_info, W_[CCCS]); - StgArrWords_words(p) = payload_words; + StgArrWords_bytes(p) = WDS(payload_words); StgArrWords_payload(p,0) = fptr; StgArrWords_payload(p,1) = ptr; StgArrWords_payload(p,2) = eptr; @@ -626,11 +634,6 @@ stg_threadStatuszh W_ ret; tso = R1; - loop: - if (TO_W_(StgTSO_what_next(tso)) == ThreadRelocated) { - tso = StgTSO__link(tso); - goto loop; - } what_next = TO_W_(StgTSO_what_next(tso)); why_blocked = TO_W_(StgTSO_why_blocked(tso)); @@ -931,9 +934,9 @@ stg_retryzh // Find the enclosing ATOMICALLY_FRAME or CATCH_RETRY_FRAME retry_pop_stack: - StgTSO_sp(CurrentTSO) = Sp; - (frame_type) = foreign "C" findRetryFrameHelper(CurrentTSO "ptr") []; - Sp = StgTSO_sp(CurrentTSO); + SAVE_THREAD_STATE(); + (frame_type) = foreign "C" findRetryFrameHelper(MyCapability(), CurrentTSO "ptr") []; + LOAD_THREAD_STATE(); frame = Sp; trec = StgTSO_trec(CurrentTSO); outer = StgTRecHeader_enclosing_trec(trec); @@ -1130,13 +1133,13 @@ stg_newMVarzh } -#define PerformTake(tso, value) \ - W_[StgTSO_sp(tso) + WDS(1)] = value; \ - W_[StgTSO_sp(tso) + WDS(0)] = stg_gc_unpt_r1_info; +#define PerformTake(stack, value) \ + W_[StgStack_sp(stack) + WDS(1)] = value; \ + W_[StgStack_sp(stack) + WDS(0)] = stg_gc_unpt_r1_info; -#define PerformPut(tso,lval) \ - StgTSO_sp(tso) = StgTSO_sp(tso) + WDS(3); \ - lval = W_[StgTSO_sp(tso) - WDS(1)]; +#define PerformPut(stack,lval) \ + StgStack_sp(stack) = StgStack_sp(stack) + WDS(3); \ + lval = W_[StgStack_sp(stack) - WDS(1)]; stg_takeMVarzh { @@ -1211,17 +1214,20 @@ loop: // There are putMVar(s) waiting... wake up the first thread on the queue tso = StgMVarTSOQueue_tso(q); - ASSERT(StgTSO_why_blocked(tso) == BlockedOnMVar::I16); - ASSERT(StgTSO_block_info(tso) == mvar); - // actually perform the putMVar for the thread that we just woke up - PerformPut(tso,StgMVar_value(mvar)); - StgMVar_head(mvar) = StgMVarTSOQueue_link(q); if (StgMVar_head(mvar) == stg_END_TSO_QUEUE_closure) { StgMVar_tail(mvar) = stg_END_TSO_QUEUE_closure; } - - // indicate that the putMVar has now completed: + + ASSERT(StgTSO_why_blocked(tso) == BlockedOnMVar::I16); + ASSERT(StgTSO_block_info(tso) == mvar); + + // actually perform the putMVar for the thread that we just woke up + W_ stack; + stack = StgTSO_stackobj(tso); + PerformPut(stack, StgMVar_value(mvar)); + + // indicate that the MVar operation has now completed. StgTSO__link(tso) = stg_END_TSO_QUEUE_closure; // no need to mark the TSO dirty, we have only written END_TSO_QUEUE. @@ -1283,17 +1289,20 @@ loop: // There are putMVar(s) waiting... wake up the first thread on the queue tso = StgMVarTSOQueue_tso(q); - ASSERT(StgTSO_why_blocked(tso) == BlockedOnMVar::I16); - ASSERT(StgTSO_block_info(tso) == mvar); - // actually perform the putMVar for the thread that we just woke up - PerformPut(tso,StgMVar_value(mvar)); - StgMVar_head(mvar) = StgMVarTSOQueue_link(q); if (StgMVar_head(mvar) == stg_END_TSO_QUEUE_closure) { StgMVar_tail(mvar) = stg_END_TSO_QUEUE_closure; } - - // indicate that the putMVar has now completed: + + ASSERT(StgTSO_why_blocked(tso) == BlockedOnMVar::I16); + ASSERT(StgTSO_block_info(tso) == mvar); + + // actually perform the putMVar for the thread that we just woke up + W_ stack; + stack = StgTSO_stackobj(tso); + PerformPut(stack, StgMVar_value(mvar)); + + // indicate that the MVar operation has now completed. StgTSO__link(tso) = stg_END_TSO_QUEUE_closure; // no need to mark the TSO dirty, we have only written END_TSO_QUEUE. @@ -1301,7 +1310,7 @@ loop: foreign "C" tryWakeupThread(MyCapability() "ptr", tso) []; unlockClosure(mvar, stg_MVAR_DIRTY_info); - RET_P(val); + RET_NP(1,val); } @@ -1368,22 +1377,25 @@ loop: // There are takeMVar(s) waiting: wake up the first one tso = StgMVarTSOQueue_tso(q); - ASSERT(StgTSO_why_blocked(tso) == BlockedOnMVar::I16); - ASSERT(StgTSO_block_info(tso) == mvar); - // actually perform the takeMVar - PerformTake(tso, val); - - if (TO_W_(StgTSO_dirty(tso)) == 0) { - foreign "C" dirty_TSO(MyCapability() "ptr", tso "ptr") []; - } - StgMVar_head(mvar) = StgMVarTSOQueue_link(q); if (StgMVar_head(mvar) == stg_END_TSO_QUEUE_closure) { StgMVar_tail(mvar) = stg_END_TSO_QUEUE_closure; } - - // indicate that the takeMVar has now completed: + + ASSERT(StgTSO_why_blocked(tso) == BlockedOnMVar::I16); + ASSERT(StgTSO_block_info(tso) == mvar); + + // actually perform the takeMVar + W_ stack; + stack = StgTSO_stackobj(tso); + PerformTake(stack, val); + + // indicate that the MVar operation has now completed. StgTSO__link(tso) = stg_END_TSO_QUEUE_closure; + + if (TO_W_(StgStack_dirty(stack)) == 0) { + foreign "C" dirty_STACK(MyCapability() "ptr", stack "ptr") []; + } foreign "C" tryWakeupThread(MyCapability() "ptr", tso) []; @@ -1423,7 +1435,7 @@ loop: /* No further takes, the MVar is now full. */ StgMVar_value(mvar) = val; unlockClosure(mvar, stg_MVAR_DIRTY_info); - jump %ENTRY_CODE(Sp(0)); + RET_N(1); } if (StgHeader_info(q) == stg_IND_info || StgHeader_info(q) == stg_MSG_NULL_info) { @@ -1431,32 +1443,33 @@ loop: goto loop; } - /* There are takeMVar(s) waiting: wake up the first one - */ // There are takeMVar(s) waiting: wake up the first one tso = StgMVarTSOQueue_tso(q); + StgMVar_head(mvar) = StgMVarTSOQueue_link(q); + if (StgMVar_head(mvar) == stg_END_TSO_QUEUE_closure) { + StgMVar_tail(mvar) = stg_END_TSO_QUEUE_closure; + } + ASSERT(StgTSO_why_blocked(tso) == BlockedOnMVar::I16); ASSERT(StgTSO_block_info(tso) == mvar); + // actually perform the takeMVar - PerformTake(tso, val); + W_ stack; + stack = StgTSO_stackobj(tso); + PerformTake(stack, val); - if (TO_W_(StgTSO_dirty(tso)) == 0) { - foreign "C" dirty_TSO(MyCapability() "ptr", tso "ptr") []; - } + // indicate that the MVar operation has now completed. + StgTSO__link(tso) = stg_END_TSO_QUEUE_closure; - StgMVar_head(mvar) = StgMVarTSOQueue_link(q); - if (StgMVar_head(mvar) == stg_END_TSO_QUEUE_closure) { - StgMVar_tail(mvar) = stg_END_TSO_QUEUE_closure; + if (TO_W_(StgStack_dirty(stack)) == 0) { + foreign "C" dirty_STACK(MyCapability() "ptr", stack "ptr") []; } - // indicate that the takeMVar has now completed: - StgTSO__link(tso) = stg_END_TSO_QUEUE_closure; - foreign "C" tryWakeupThread(MyCapability() "ptr", tso) []; unlockClosure(mvar, stg_MVAR_DIRTY_info); - jump %ENTRY_CODE(Sp(0)); + RET_N(1); } @@ -1522,7 +1535,7 @@ stg_newBCOzh bitmap_arr = R5; - words = BYTES_TO_WDS(SIZEOF_StgBCO) + StgArrWords_words(bitmap_arr); + words = BYTES_TO_WDS(SIZEOF_StgBCO) + BYTE_ARR_WDS(bitmap_arr); bytes = WDS(words); ALLOC_PRIM( bytes, R1_PTR&R2_PTR&R3_PTR&R5_PTR, stg_newBCOzh ); @@ -1540,7 +1553,7 @@ stg_newBCOzh W_ i; i = 0; for: - if (i < StgArrWords_words(bitmap_arr)) { + if (i < BYTE_ARR_WDS(bitmap_arr)) { StgBCO_bitmap(bco,i) = StgArrWords_payload(bitmap_arr,i); i = i + 1; goto for; @@ -1634,7 +1647,7 @@ for: is promoted. */ SET_HDR(nptrs_arr, stg_ARR_WORDS_info, W_[CCCS]); - StgArrWords_words(nptrs_arr) = nptrs; + StgArrWords_bytes(nptrs_arr) = WDS(nptrs); p = 0; for2: if(p < nptrs) { @@ -1980,17 +1993,28 @@ stg_getSparkzh W_ spark; #ifndef THREADED_RTS - RET_NP(0,ghczmprim_GHCziBool_False_closure); + RET_NP(0,ghczmprim_GHCziTypes_False_closure); #else (spark) = foreign "C" findSpark(MyCapability()); if (spark != 0) { RET_NP(1,spark); } else { - RET_NP(0,ghczmprim_GHCziBool_False_closure); + RET_NP(0,ghczmprim_GHCziTypes_False_closure); } #endif } +stg_numSparkszh +{ + W_ n; +#ifdef THREADED_RTS + (n) = foreign "C" dequeElements(Capability_sparks(MyCapability())); +#else + n = 0; +#endif + RET_N(n); +} + stg_traceEventzh { W_ msg;