X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=rts%2FCapability.c;h=82343597ed1260a5f50bcd42a24a498b810fab42;hp=5f54ecae4d034785344e1e74166115da93e693ba;hb=890f22ef8eff8dbb5b31fa221dfce65a7b84c202;hpb=7408b39235bccdcde48df2a73337ff976fbc09b7 diff --git a/rts/Capability.c b/rts/Capability.c index 5f54eca..8234359 100644 --- a/rts/Capability.c +++ b/rts/Capability.c @@ -62,9 +62,8 @@ Capability * rts_unsafeGetMyCapability (void) STATIC_INLINE rtsBool globalWorkToDo (void) { - return blackholes_need_checking - || sched_state >= SCHED_INTERRUPTING - ; + return sched_state >= SCHED_INTERRUPTING + || recent_activity == ACTIVITY_INACTIVE; // need to check for deadlock } #endif @@ -220,6 +219,7 @@ initCapability( Capability *cap, nat i ) initMutex(&cap->lock); cap->running_task = NULL; // indicates cap is free cap->spare_workers = NULL; + cap->n_spare_workers = 0; cap->suspended_ccalls = NULL; cap->returning_tasks_hd = NULL; cap->returning_tasks_tl = NULL; @@ -461,9 +461,24 @@ releaseCapabilityAndQueueWorker (Capability* cap USED_IF_THREADS) // in which case it is not replaced on the spare_worker queue. // This happens when the system is shutting down (see // Schedule.c:workerStart()). - if (!isBoundTask(task) && !task->stopped) { - task->next = cap->spare_workers; - cap->spare_workers = task; + if (!isBoundTask(task) && !task->stopped) + { + if (cap->n_spare_workers < MAX_SPARE_WORKERS) + { + task->next = cap->spare_workers; + cap->spare_workers = task; + cap->n_spare_workers++; + } + else + { + debugTrace(DEBUG_sched, "%d spare workers already, exiting", + cap->n_spare_workers); + releaseCapability_(cap,rtsFalse); + // hold the lock until after workerTaskStop; c.f. scheduleWorker() + workerTaskStop(task); + RELEASE_LOCK(&cap->lock); + shutdownThread(); + } } // Bound tasks just float around attached to their TSOs. @@ -620,7 +635,8 @@ yieldCapability (Capability** pCap, Task *task) } cap->spare_workers = task->next; task->next = NULL; - } + cap->n_spare_workers--; + } cap->running_task = task; RELEASE_LOCK(&cap->lock); break; @@ -637,43 +653,6 @@ yieldCapability (Capability** pCap, Task *task) } /* ---------------------------------------------------------------------------- - * Wake up a thread on a Capability. - * - * This is used when the current Task is running on a Capability and - * wishes to wake up a thread on a different Capability. - * ------------------------------------------------------------------------- */ - -void -wakeupThreadOnCapability (Capability *cap, - Capability *other_cap, - StgTSO *tso) -{ - MessageWakeup *msg; - - // ASSUMES: cap->lock is held (asserted in wakeupThreadOnCapability) - if (tso->bound) { - ASSERT(tso->bound->task->cap == tso->cap); - tso->bound->task->cap = other_cap; - } - tso->cap = other_cap; - - ASSERT(tso->why_blocked != BlockedOnMsgWakeup || - tso->block_info.closure->header.info == &stg_IND_info); - - ASSERT(tso->block_info.closure->header.info != &stg_MSG_WAKEUP_info); - - msg = (MessageWakeup*) allocate(cap, sizeofW(MessageWakeup)); - msg->header.info = &stg_MSG_WAKEUP_info; - msg->tso = tso; - tso->block_info.closure = (StgClosure *)msg; - dirty_TSO(cap, tso); - write_barrier(); - tso->why_blocked = BlockedOnMsgWakeup; - - sendMessage(other_cap, (Message*)msg); -} - -/* ---------------------------------------------------------------------------- * prodCapability * * If a Capability is currently idle, wake up a Task on it. Used to @@ -746,12 +725,13 @@ shutdownCapability (Capability *cap, Task *task, rtsBool safe) if (!osThreadIsAlive(t->id)) { debugTrace(DEBUG_sched, "worker thread %p has died unexpectedly", (void *)t->id); - if (!prev) { - cap->spare_workers = t->next; - } else { - prev->next = t->next; - } - prev = t; + cap->n_spare_workers--; + if (!prev) { + cap->spare_workers = t->next; + } else { + prev->next = t->next; + } + prev = t; } } } @@ -857,7 +837,7 @@ freeCapabilities (void) void markSomeCapabilities (evac_fn evac, void *user, nat i0, nat delta, - rtsBool prune_sparks USED_IF_THREADS) + rtsBool no_mark_sparks USED_IF_THREADS) { nat i; Capability *cap; @@ -881,9 +861,7 @@ markSomeCapabilities (evac_fn evac, void *user, nat i0, nat delta, } #if defined(THREADED_RTS) - if (prune_sparks) { - pruneSparkQueue (evac, user, cap); - } else { + if (!no_mark_sparks) { traverseSparkQueue (evac, user, cap); } #endif @@ -906,24 +884,3 @@ markCapabilities (evac_fn evac, void *user) Messages -------------------------------------------------------------------------- */ -#ifdef THREADED_RTS - -void sendMessage(Capability *cap, Message *msg) -{ - ACQUIRE_LOCK(&cap->lock); - - msg->link = cap->inbox; - cap->inbox = msg; - - if (cap->running_task == NULL) { - cap->running_task = myTask(); - // precond for releaseCapability_() - releaseCapability_(cap,rtsFalse); - } else { - contextSwitchCapability(cap); - } - - RELEASE_LOCK(&cap->lock); -} - -#endif // THREADED_RTS