X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2FCapability.c;h=bffb7356127700cd21f5066bc27563c89b60b7ba;hb=6b89acb468c0db3337b831790f96bee4d9b54bfe;hp=2fcd72c12ab90d3679fb49e218818c60fe226d30;hpb=f9ce05ef56187d981b5d1af51e3f53fc6f202d5b;p=ghc-hetmet.git diff --git a/rts/Capability.c b/rts/Capability.c index 2fcd72c..bffb735 100644 --- a/rts/Capability.c +++ b/rts/Capability.c @@ -219,13 +219,16 @@ 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; cap->inbox = (Message*)END_TSO_QUEUE; cap->sparks_created = 0; + cap->sparks_dud = 0; cap->sparks_converted = 0; - cap->sparks_pruned = 0; + cap->sparks_gcd = 0; + cap->sparks_fizzled = 0; #endif cap->f.stgEagerBlackholeInfo = (W_)&__stg_EAGER_BLACKHOLE_info; @@ -455,14 +458,33 @@ releaseCapabilityAndQueueWorker (Capability* cap USED_IF_THREADS) task = cap->running_task; + // If the Task is stopped, we shouldn't be yielding, we should + // be just exiting. + ASSERT(!task->stopped); + // If the current task is a worker, save it on the spare_workers // list of this Capability. A worker can mark itself as stopped, // 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)) + { + 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. @@ -619,7 +641,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; @@ -708,12 +731,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; } } }