X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2FCapability.c;h=0e4d5a6a30594e6e8d8e52d8d3b1626bc7dcb226;hb=ba67234542412c2ca6656dbeadb7d225bc94d4b2;hp=fcfca3c733ece0a12a9a97aec377616947e2aefe;hpb=e8d7985d56595f6b8004546bedc41627ca70c528;p=ghc-hetmet.git diff --git a/rts/Capability.c b/rts/Capability.c index fcfca3c..0e4d5a6 100644 --- a/rts/Capability.c +++ b/rts/Capability.c @@ -18,32 +18,46 @@ #include "PosixSource.h" #include "Rts.h" -#include "RtsUtils.h" -#include "RtsFlags.h" -#include "STM.h" -#include "OSThreads.h" + #include "Capability.h" #include "Schedule.h" #include "Sparks.h" #include "Trace.h" -#include "GC.h" +#include "sm/GC.h" // for gcWorkerThread() +#include "STM.h" +#include "RtsUtils.h" // one global capability, this is the Capability for non-threaded // builds, and for +RTS -N1 Capability MainCapability; -nat n_capabilities; +nat n_capabilities = 0; Capability *capabilities = NULL; // Holds the Capability which last became free. This is used so that // an in-call has a chance of quickly finding a free Capability. // Maintaining a global free list of Capabilities would require global // locking, so we don't do that. -Capability *last_free_capability; +Capability *last_free_capability = NULL; /* GC indicator, in scope for the scheduler, init'ed to false */ volatile StgWord waiting_for_gc = 0; +/* Let foreign code get the current Capability -- assuming there is one! + * This is useful for unsafe foreign calls because they are called with + * the current Capability held, but they are not passed it. For example, + * see see the integer-gmp package which calls allocateLocal() in its + * stgAllocForGMP() function (which gets called by gmp functions). + * */ +Capability * rts_unsafeGetMyCapability (void) +{ +#if defined(THREADED_RTS) + return myTask()->cap; +#else + return &MainCapability; +#endif +} + #if defined(THREADED_RTS) STATIC_INLINE rtsBool globalWorkToDo (void) @@ -81,7 +95,7 @@ findSpark (Capability *cap) cap->sparks_converted++; // Post event for running a spark from capability's own pool. - postEvent(cap, EVENT_RUN_SPARK, cap->r.rCurrentTSO->id, 0); + traceSchedEvent(cap, EVENT_RUN_SPARK, cap->r.rCurrentTSO, 0); return spark; } @@ -113,14 +127,10 @@ findSpark (Capability *cap) } if (spark != NULL) { - debugTrace(DEBUG_sched, - "cap %d: Stole a spark from capability %d", - cap->no, robbed->no); cap->sparks_converted++; - postEvent(cap, EVENT_STEAL_SPARK, - cap->r.rCurrentTSO->id, robbed->no); - + traceSchedEvent(cap, EVENT_STEAL_SPARK, + cap->r.rCurrentTSO, robbed->no); return spark; } @@ -220,8 +230,8 @@ initCapability( Capability *cap, nat i ) #endif cap->f.stgEagerBlackholeInfo = (W_)&__stg_EAGER_BLACKHOLE_info; - cap->f.stgGCEnter1 = (F_)__stg_gc_enter_1; - cap->f.stgGCFun = (F_)__stg_gc_fun; + cap->f.stgGCEnter1 = (StgFunPtr)__stg_gc_enter_1; + cap->f.stgGCFun = (StgFunPtr)__stg_gc_fun; cap->mut_lists = stgMallocBytes(sizeof(bdescr *) * RtsFlags.GcFlags.generations, @@ -486,7 +496,7 @@ waitForReturnCapability (Capability **pCap, Task *task) if (cap == NULL) { // Try last_free_capability first cap = last_free_capability; - if (!cap->running_task) { + if (cap->running_task) { nat i; // otherwise, search for a free capability cap = NULL; @@ -566,10 +576,9 @@ yieldCapability (Capability** pCap, Task *task) Capability *cap = *pCap; if (waiting_for_gc == PENDING_GC_PAR) { - debugTrace(DEBUG_sched, "capability %d: becoming a GC thread", cap->no); - postEvent(cap, EVENT_GC_START, 0, 0); + traceSchedEvent(cap, EVENT_GC_START, 0, 0); gcWorkerThread(cap); - postEvent(cap, EVENT_GC_END, 0, 0); + traceSchedEvent(cap, EVENT_GC_END, 0, 0); return; } @@ -776,8 +785,7 @@ shutdownCapability (Capability *cap, Task *task, rtsBool safe) continue; } - postEvent(cap, EVENT_SHUTDOWN, 0, 0); - debugTrace(DEBUG_sched, "capability %d is stopped.", cap->no); + traceSchedEvent(cap, EVENT_SHUTDOWN, 0, 0); RELEASE_LOCK(&cap->lock); break; } @@ -819,7 +827,7 @@ static void freeCapability (Capability *cap) { stgFree(cap->mut_lists); -#if defined(THREADED_RTS) || defined(PARALLEL_HASKELL) +#if defined(THREADED_RTS) freeSparkPool(cap->sparks); #endif } @@ -866,8 +874,6 @@ markSomeCapabilities (evac_fn evac, void *user, nat i0, nat delta, #endif for (task = cap->suspended_ccalling_tasks; task != NULL; task=task->next) { - debugTrace(DEBUG_sched, - "evac'ing suspended TSO %lu", (unsigned long)task->suspended_tso->id); evac(user, (StgClosure **)(void *)&task->suspended_tso); }