X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2FCapability.c;h=c37ec4e0ad0b41abf74dc4d00fbdb92d46ccb8bf;hb=cd2773d8030b1c978bfda6a30f396592a4a94be4;hp=0e4d5a6a30594e6e8d8e52d8d3b1626bc7dcb226;hpb=a5288c551349a0adab0d931a429b10a096d9444d;p=ghc-hetmet.git diff --git a/rts/Capability.c b/rts/Capability.c index 0e4d5a6..c37ec4e 100644 --- a/rts/Capability.c +++ b/rts/Capability.c @@ -77,37 +77,40 @@ findSpark (Capability *cap) rtsBool retry; nat i = 0; - if (!emptyRunQueue(cap)) { + if (!emptyRunQueue(cap) || cap->returning_tasks_hd != NULL) { // If there are other threads, don't try to run any new // sparks: sparks might be speculative, we don't want to take // resources away from the main computation. return 0; } - // first try to get a spark from our own pool. - // We should be using reclaimSpark(), because it works without - // needing any atomic instructions: - // spark = reclaimSpark(cap->sparks); - // However, measurements show that this makes at least one benchmark - // slower (prsa) and doesn't affect the others. - spark = tryStealSpark(cap); - if (spark != NULL) { - cap->sparks_converted++; + do { + retry = rtsFalse; - // Post event for running a spark from capability's own pool. - traceSchedEvent(cap, EVENT_RUN_SPARK, cap->r.rCurrentTSO, 0); + // first try to get a spark from our own pool. + // We should be using reclaimSpark(), because it works without + // needing any atomic instructions: + // spark = reclaimSpark(cap->sparks); + // However, measurements show that this makes at least one benchmark + // slower (prsa) and doesn't affect the others. + spark = tryStealSpark(cap); + if (spark != NULL) { + cap->sparks_converted++; - return spark; - } + // Post event for running a spark from capability's own pool. + traceEventRunSpark(cap, cap->r.rCurrentTSO); - if (n_capabilities == 1) { return NULL; } // makes no sense... + return spark; + } + if (!emptySparkPoolCap(cap)) { + retry = rtsTrue; + } - debugTrace(DEBUG_sched, - "cap %d: Trying to steal work from other capabilities", - cap->no); + if (n_capabilities == 1) { return NULL; } // makes no sense... - do { - retry = rtsFalse; + debugTrace(DEBUG_sched, + "cap %d: Trying to steal work from other capabilities", + cap->no); /* visit cap.s 0..n-1 in sequence until a theft succeeds. We could start at a random place instead of 0 as well. */ @@ -129,8 +132,7 @@ findSpark (Capability *cap) if (spark != NULL) { cap->sparks_converted++; - traceSchedEvent(cap, EVENT_STEAL_SPARK, - cap->r.rCurrentTSO, robbed->no); + traceEventStealSpark(cap, cap->r.rCurrentTSO, robbed->no); return spark; } @@ -210,7 +212,6 @@ initCapability( Capability *cap, nat i ) cap->no = i; cap->in_haskell = rtsFalse; - cap->in_gc = rtsFalse; cap->run_queue_hd = END_TSO_QUEUE; cap->run_queue_tl = END_TSO_QUEUE; @@ -250,6 +251,7 @@ initCapability( Capability *cap, nat i ) cap->free_trec_headers = NO_TREC; cap->transaction_tokens = 0; cap->context_switch = 0; + cap->pinned_object_block = NULL; } /* --------------------------------------------------------------------------- @@ -392,7 +394,10 @@ releaseCapability_ (Capability* cap, // give this Capability to the appropriate Task. if (!emptyRunQueue(cap) && cap->run_queue_hd->bound) { // Make sure we're not about to try to wake ourselves up - ASSERT(task != cap->run_queue_hd->bound); + // ASSERT(task != cap->run_queue_hd->bound); + // assertion is false: in schedule() we force a yield after + // ThreadBlocked, but the thread may be back on the run queue + // by now. task = cap->run_queue_hd->bound; giveCapabilityToTask(cap,task); return; @@ -576,9 +581,9 @@ yieldCapability (Capability** pCap, Task *task) Capability *cap = *pCap; if (waiting_for_gc == PENDING_GC_PAR) { - traceSchedEvent(cap, EVENT_GC_START, 0, 0); + traceEventGcStart(cap); gcWorkerThread(cap); - traceSchedEvent(cap, EVENT_GC_END, 0, 0); + traceEventGcEnd(cap); return; } @@ -785,7 +790,7 @@ shutdownCapability (Capability *cap, Task *task, rtsBool safe) continue; } - traceSchedEvent(cap, EVENT_SHUTDOWN, 0, 0); + traceEventShutdown(cap); RELEASE_LOCK(&cap->lock); break; } @@ -827,6 +832,7 @@ static void freeCapability (Capability *cap) { stgFree(cap->mut_lists); + stgFree(cap->saved_mut_lists); #if defined(THREADED_RTS) freeSparkPool(cap->sparks); #endif