X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FCapability.h;h=450bf74275ed993880b78b6029b238ddec906061;hb=423d477bfecd490de1449c59325c8776f91d7aac;hp=cecbc8b98db75430a9284f2be9b0110b261951f6;hpb=199b5c0766a2c7888544a970d35ba4d8fd889a07;p=ghc-hetmet.git diff --git a/ghc/rts/Capability.h b/ghc/rts/Capability.h index cecbc8b..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,37 +19,94 @@ * (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); + +// 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); -extern void initCapabilities(void); -extern void grabCapability(Capability** cap); -extern void releaseCapability(Capability* cap); +// Signals that the next time a capability becomes free, it should +// be transfered to an ordinary worker thread. +// +extern void passCapabilityToWorker( void ); -#if defined(SMP) -extern nat rts_n_free_capabilities; /* 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; -static inline nat getFreeCapabilities() +static inline rtsBool needToYieldToReturningWorker(void) +{ + return rts_n_waiting_workers > 0; +} + +static inline nat getFreeCapabilities (void) { return rts_n_free_capabilities; } -static inline rtsBool noFreeCapabilities() +static inline rtsBool noCapabilities (void) { return (rts_n_free_capabilities == 0); } -static inline rtsBool allFreeCapabilities() +static inline rtsBool allFreeCapabilities (void) { - return (rts_n_free_capabilities == RtsFlags.ParFlags.nNodes); + return (rts_n_free_capabilities == 1); } -#endif /* SMP */ +#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__ */