X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2FCapability.h;h=77132e318ea57891833f19161fbf09fdb66148b6;hb=c7ea7c15942c6369bcca2cc13012d228a80fe926;hp=dc0a28ea57b8f8c622019ddadb0902d6d3b2dbba;hpb=4af25e1a72f2d0f1f523fe5b13c71f1b3dc7a5a5;p=ghc-hetmet.git diff --git a/rts/Capability.h b/rts/Capability.h index dc0a28e..77132e3 100644 --- a/rts/Capability.h +++ b/rts/Capability.h @@ -46,6 +46,9 @@ struct Capability_ { // catching unsafe call-ins. rtsBool in_haskell; + // true if this Capability is currently in the GC + rtsBool in_gc; + // The run queue. The Task owning this Capability has exclusive // access to its run queue, so can wake up threads without // taking a lock, and the common path through the scheduler is @@ -62,10 +65,12 @@ struct Capability_ { Task *suspended_ccalling_tasks; // One mutable list per generation, so we don't need to take any - // locks when updating an old-generation thunk. These - // mini-mut-lists are moved onto the respective gen->mut_list at - // each GC. + // locks when updating an old-generation thunk. This also lets us + // keep track of which closures this CPU has been mutating, so we + // can traverse them using the right thread during GC and avoid + // unnecessarily moving the data from one cache to another. bdescr **mut_lists; + bdescr **saved_mut_lists; // tmp use during GC // Context switch flag. We used to have one global flag, now one // per capability. Locks required : none (conflicts are harmless) @@ -109,7 +114,10 @@ struct Capability_ { } // typedef Capability is defined in RtsAPI.h // Capabilities are stored in an array, so make sure that adjacent // Capabilities don't share any cache-lines: - ATTRIBUTE_ALIGNED(64); +#ifndef mingw32_HOST_OS + ATTRIBUTE_ALIGNED(64) +#endif + ; #if defined(THREADED_RTS) @@ -140,7 +148,7 @@ struct Capability_ { INLINE_HEADER Capability * regTableToCapability (StgRegTable *reg) { - return (Capability *)((void *)((unsigned char*)reg - sizeof(StgFunTable))); + return (Capability *)((void *)((unsigned char*)reg - FIELD_OFFSET(Capability,r))); } // Initialise the available capabilities. @@ -182,6 +190,8 @@ extern Capability *capabilities; extern Capability *last_free_capability; // GC indicator, in scope for the scheduler +#define PENDING_GC_SEQ 1 +#define PENDING_GC_PAR 2 extern volatile StgWord waiting_for_gc; // Acquires a capability at a return point. If *cap is non-NULL, then @@ -228,6 +238,7 @@ void wakeupThreadOnCapability (Capability *my_cap, Capability *other_cap, // need to service some global event. // void prodOneCapability (void); +void prodCapability (Capability *cap, Task *task); // Similar to prodOneCapability(), but prods all of them. // @@ -242,9 +253,13 @@ void shutdownCapability (Capability *cap, Task *task, rtsBool wait_foreign); // rtsBool tryGrabCapability (Capability *cap, Task *task); -// Try to steal a spark from other Capabilities +// Try to find a spark to run +// +StgClosure *findSpark (Capability *cap); + +// True if any capabilities have sparks // -rtsBool stealWork (Capability *cap); +rtsBool anySparks (void); INLINE_HEADER rtsBool emptySparkPoolCap (Capability *cap); INLINE_HEADER nat sparkPoolSizeCap (Capability *cap); @@ -262,8 +277,8 @@ extern void grabCapability (Capability **pCap); // cause all capabilities to context switch as soon as possible. void setContextSwitches(void); -// Free a capability on exit -void freeCapability (Capability *cap); +// Free all capabilities +void freeCapabilities (void); // FOr the GC: void markSomeCapabilities (evac_fn evac, void *user, nat i0, nat delta,