X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2FCapability.c;h=4d5748cec27274ed9f003461e03be8d2157a7cf4;hb=582a99f2042ed92aa557b0823fd49ac01716cf26;hp=0f0362100362dbff4ea0898df5aeab665ed0ab62;hpb=4753cf734c79ad196ef4411393a1516465302f71;p=ghc-hetmet.git diff --git a/rts/Capability.c b/rts/Capability.c index 0f03621..4d5748c 100644 --- a/rts/Capability.c +++ b/rts/Capability.c @@ -161,6 +161,7 @@ initCapability( Capability *cap, nat i ) cap->free_trec_chunks = END_STM_CHUNK_LIST; cap->free_trec_headers = NO_TREC; cap->transaction_tokens = 0; + cap->context_switch = 0; } /* --------------------------------------------------------------------------- @@ -218,6 +219,19 @@ initCapabilities( void ) } /* ---------------------------------------------------------------------------- + * setContextSwitches: cause all capabilities to context switch as + * soon as possible. + * ------------------------------------------------------------------------- */ + +void setContextSwitches(void) +{ + nat i; + for (i=0; i < n_capabilities; i++) { + capabilities[i].context_switch = 1; + } +} + +/* ---------------------------------------------------------------------------- * Give a Capability to a Task. The task must currently be sleeping * on its condition variable. * @@ -540,57 +554,41 @@ yieldCapability (Capability** pCap, Task *task) * ------------------------------------------------------------------------- */ void -wakeupThreadOnCapability (Capability *cap, StgTSO *tso) +wakeupThreadOnCapability (Capability *my_cap, + Capability *other_cap, + StgTSO *tso) { - ASSERT(tso->cap == cap); - ASSERT(tso->bound ? tso->bound->cap == cap : 1); - ASSERT_LOCK_HELD(&cap->lock); + ACQUIRE_LOCK(&other_cap->lock); - tso->cap = cap; + // ASSUMES: cap->lock is held (asserted in wakeupThreadOnCapability) + if (tso->bound) { + ASSERT(tso->bound->cap == tso->cap); + tso->bound->cap = other_cap; + } + tso->cap = other_cap; - if (cap->running_task == NULL) { + ASSERT(tso->bound ? tso->bound->cap == other_cap : 1); + + if (other_cap->running_task == NULL) { // nobody is running this Capability, we can add our thread // directly onto the run queue and start up a Task to run it. - appendToRunQueue(cap,tso); - // start it up - cap->running_task = myTask(); // precond for releaseCapability_() - trace(TRACE_sched, "resuming capability %d", cap->no); - releaseCapability_(cap); + other_cap->running_task = myTask(); + // precond for releaseCapability_() and appendToRunQueue() + + appendToRunQueue(other_cap,tso); + + trace(TRACE_sched, "resuming capability %d", other_cap->no); + releaseCapability_(other_cap); } else { - appendToWakeupQueue(cap,tso); + appendToWakeupQueue(my_cap,other_cap,tso); + other_cap->context_switch = 1; // someone is running on this Capability, so it cannot be // freed without first checking the wakeup queue (see // releaseCapability_). } -} -void -wakeupThreadOnCapability_lock (Capability *cap, StgTSO *tso) -{ - ACQUIRE_LOCK(&cap->lock); - migrateThreadToCapability (cap, tso); - RELEASE_LOCK(&cap->lock); -} - -void -migrateThreadToCapability (Capability *cap, StgTSO *tso) -{ - // ASSUMES: cap->lock is held (asserted in wakeupThreadOnCapability) - if (tso->bound) { - ASSERT(tso->bound->cap == tso->cap); - tso->bound->cap = cap; - } - tso->cap = cap; - wakeupThreadOnCapability(cap,tso); -} - -void -migrateThreadToCapability_lock (Capability *cap, StgTSO *tso) -{ - ACQUIRE_LOCK(&cap->lock); - migrateThreadToCapability (cap, tso); - RELEASE_LOCK(&cap->lock); + RELEASE_LOCK(&other_cap->lock); } /* ---------------------------------------------------------------------------- @@ -818,7 +816,7 @@ markSomeCapabilities (evac_fn evac, void *user, nat i0, nat delta) } #if defined(THREADED_RTS) - markSparkQueue (evac, user, cap); + traverseSparkQueue (evac, user, cap); #endif }