X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=rts%2FCapability.h;h=d8eba0d733f17b4c5334e5eb5f99a5a511c5295d;hp=fb199e2a3e32882d2a57f18b4e7f4eaa37eec3a2;hb=f4692220c7cbdadaa633f50eb2b30b59edb30183;hpb=a2a67cd520b9841114d69a87a423dabcb3b4368e diff --git a/rts/Capability.h b/rts/Capability.h index fb199e2..d8eba0d 100644 --- a/rts/Capability.h +++ b/rts/Capability.h @@ -22,6 +22,8 @@ #include "Task.h" #include "Sparks.h" +BEGIN_RTS_PRIVATE + struct Capability_ { // State required by the STG virtual machine when running Haskell // code. During STG execution, the BaseReg register always points @@ -41,9 +43,6 @@ 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 @@ -57,7 +56,7 @@ struct Capability_ { // the suspended TSOs easily. Hence, when migrating a Task from // the returning_tasks list, we must also migrate its entry from // this list. - Task *suspended_ccalling_tasks; + InCall *suspended_ccalls; // One mutable list per generation, so we don't need to take any // locks when updating an old-generation thunk. This also lets us @@ -67,6 +66,9 @@ struct Capability_ { bdescr **mut_lists; bdescr **saved_mut_lists; // tmp use during GC + // block for allocating pinned objects into + bdescr *pinned_object_block; + // Context switch flag. We used to have one global flag, now one // per capability. Locks required : none (conflicts are harmless) int context_switch; @@ -86,11 +88,8 @@ struct Capability_ { Task *returning_tasks_hd; // Singly-linked, with head/tail Task *returning_tasks_tl; - // A list of threads to append to this Capability's run queue at - // the earliest opportunity. These are threads that have been - // woken up by another Capability. - StgTSO *wakeup_queue_hd; - StgTSO *wakeup_queue_tl; + // Messages, or END_TSO_QUEUE. + Message *inbox; SparkPool *sparks; @@ -200,7 +199,9 @@ extern volatile StgWord waiting_for_gc; // void waitForReturnCapability (Capability **cap/*in/out*/, Task *task); -INLINE_HEADER void recordMutableCap (StgClosure *p, Capability *cap, nat gen); +EXTERN_INLINE void recordMutableCap (StgClosure *p, Capability *cap, nat gen); + +EXTERN_INLINE void recordClosureMutated (Capability *cap, StgClosure *p); #if defined(THREADED_RTS) @@ -223,12 +224,6 @@ void yieldCapability (Capability** pCap, Task *task); // void waitForCapability (Task *task, Mutex *mutex, Capability **pCap); -// Wakes up a thread on a Capability (probably a different Capability -// from the one held by the current Task). -// -void wakeupThreadOnCapability (Capability *my_cap, Capability *other_cap, - StgTSO *tso); - // Wakes up a worker thread on just one Capability, used when we // need to service some global event. // @@ -283,16 +278,27 @@ void markCapabilities (evac_fn evac, void *user); void traverseSparkQueues (evac_fn evac, void *user); /* ----------------------------------------------------------------------------- + Messages + -------------------------------------------------------------------------- */ + +#ifdef THREADED_RTS + +INLINE_HEADER rtsBool emptyInbox(Capability *cap);; + +#endif // THREADED_RTS + +/* ----------------------------------------------------------------------------- * INLINE functions... private below here * -------------------------------------------------------------------------- */ -INLINE_HEADER void +EXTERN_INLINE void recordMutableCap (StgClosure *p, Capability *cap, nat gen) { bdescr *bd; // We must own this Capability in order to modify its mutable list. - ASSERT(cap->running_task == myTask()); + // ASSERT(cap->running_task == myTask()); + // NO: assertion is violated by performPendingThrowTos() bd = cap->mut_lists[gen]; if (bd->free >= bd->start + BLOCK_SIZE_W) { bdescr *new_bd; @@ -304,6 +310,15 @@ recordMutableCap (StgClosure *p, Capability *cap, nat gen) *bd->free++ = (StgWord)p; } +EXTERN_INLINE void +recordClosureMutated (Capability *cap, StgClosure *p) +{ + bdescr *bd; + bd = Bdescr((StgPtr)p); + if (bd->gen_no != 0) recordMutableCap(p,cap,bd->gen_no); +} + + #if defined(THREADED_RTS) INLINE_HEADER rtsBool emptySparkPoolCap (Capability *cap) @@ -330,4 +345,15 @@ contextSwitchCapability (Capability *cap) cap->context_switch = 1; } +#ifdef THREADED_RTS + +INLINE_HEADER rtsBool emptyInbox(Capability *cap) +{ + return (cap->inbox == (Message*)END_TSO_QUEUE); +} + +#endif + +END_RTS_PRIVATE + #endif /* CAPABILITY_H */