[project @ 2004-08-13 13:04:50 by simonmar]
[ghc-hetmet.git] / ghc / rts / Capability.h
index 6aef3db..450bf74 100644 (file)
@@ -1,6 +1,6 @@
 /* ---------------------------------------------------------------------------
  *
- * (c) The GHC Team, 2001
+ * (c) The GHC Team, 2001-2003
  *
  * Capabilities
  *
  * (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__ */