X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FCapability.h;h=450bf74275ed993880b78b6029b238ddec906061;hb=423d477bfecd490de1449c59325c8776f91d7aac;hp=6aef3dbad21f4e9f3edf6280fe4b598e1a26d76e;hpb=efa41d9d5eada7aa3230a2bd03b97a8b7025ef2e;p=ghc-hetmet.git diff --git a/ghc/rts/Capability.h b/ghc/rts/Capability.h index 6aef3db..450bf74 100644 --- a/ghc/rts/Capability.h +++ b/ghc/rts/Capability.h @@ -1,6 +1,6 @@ /* --------------------------------------------------------------------------- * - * (c) The GHC Team, 2001 + * (c) The GHC Team, 2001-2003 * * Capabilities * @@ -19,26 +19,71 @@ * (the main, and only, consumer of this interface is the scheduler). * * --------------------------------------------------------------------------*/ + #ifndef __CAPABILITY_H__ #define __CAPABILITY_H__ -#include "RtsFlags.h" -/* ToDo: assume that RtsFlags.h has been included at usage sites of Capability.h? */ -#if !defined(SMP) -extern Capability MainCapability; -#endif +// Initialised the available capabilities. +// +extern void initCapabilities( void ); + +// Releases a capability +// +extern void releaseCapability( Capability* cap ); + +#ifdef RTS_SUPPORTS_THREADS +// Gives up the current capability IFF there is a higher-priority +// thread waiting for it. This happens in one of two ways: +// +// (a) we are passing the capability to another OS thread, so +// that it can run a bound Haskell thread, or +// +// (b) there is an OS thread waiting to return from a foreign call +// +// On return: *pCap is NULL if the capability was released. The +// current worker thread should then re-acquire it using +// waitForCapability(). +// +extern void yieldCapability( Capability **pCap ); + +// Acquires a capability for doing some work. +// +// If the current OS thread is bound to a particular Haskell thread, +// then pThreadCond points to a condition variable for waking up this +// OS thread when its Haskell thread is ready to run. +// +// On return: pCap points to the capability. +extern void waitForCapability( Mutex* pMutex, Capability** pCap, + Condition *pThreadCond ); + +// Acquires a capability at a return point. +// +// OS threads waiting in this function get priority over those waiting +// in waitForWorkCapability(). +// +// On return: pCap points to the capability. +extern void waitForReturnCapability(Mutex* pMutex, Capability** pCap); -extern void initCapabilities(void); -extern void grabCapability(Capability** pCap); -extern void releaseCapability(Capability* cap); +// Signals that the next time a capability becomes free, it should +// be transfered to a particular OS thread, identified by the +// condition variable pTargetThreadCond. +// +extern void passCapability(Condition *pTargetThreadCond); + +// Signals that the next time a capability becomes free, it should +// be transfered to an ordinary worker thread. +// +extern void passCapabilityToWorker( void ); -#if defined(RTS_SUPPORTS_THREADS) -/* total number of available capabilities */ extern nat rts_n_free_capabilities; +/* number of worker threads waiting for a return capability + */ extern nat rts_n_waiting_workers; -extern void grabReturnCapability(Capability** pCap); -extern void yieldCapability(Capability* cap); +static inline rtsBool needToYieldToReturningWorker(void) +{ + return rts_n_waiting_workers > 0; +} static inline nat getFreeCapabilities (void) { @@ -52,13 +97,16 @@ static inline rtsBool noCapabilities (void) static inline rtsBool allFreeCapabilities (void) { -# if defined(SMP) - return (rts_n_free_capabilities == RtsFlags.ParFlags.nNodes); -# else return (rts_n_free_capabilities == 1); -# endif } -#endif /* RTS_SUPPORTS_THREADS */ +#else // !RTS_SUPPORTS_THREADS + +// Grab a capability. (Only in the non-threaded RTS; in the threaded +// RTS one of the waitFor*Capability() functions must be used). +// +extern void grabCapability( Capability **pCap ); + +#endif // !RTS_SUPPORTS_THREADS #endif /* __CAPABILITY_H__ */