#include "OSThreads.h"
#include "Capability.h"
#include "Schedule.h" /* to get at EMPTY_RUN_QUEUE() */
-#include "Signals.h" /* to get at handleSignalsInThisThread() */
#if !defined(SMP)
Capability MainCapability; /* for non-SMP, we have one global capability */
#endif
+Capability *capabilities = NULL;
nat rts_n_free_capabilities;
#if defined(RTS_SUPPORTS_THREADS)
static void
initCapability( Capability *cap )
{
+ cap->r.rInHaskell = rtsFalse;
cap->f.stgGCEnter1 = (F_)__stg_gc_enter_1;
cap->f.stgGCFun = (F_)__stg_gc_fun;
}
-/* -----------------------------------------------------------------------------
- * Function: initCapabilities_(nat)
- *
- * Purpose: upon startup, allocate and fill in table
- * holding 'n' Capabilities. Only for SMP, since
- * it is the only build that supports multiple
- * capabilities within the RTS.
- * -------------------------------------------------------------------------- */
-#if defined(SMP)
-static void
-initCapabilities_(nat n)
-{
- nat i;
- Capability *cap, *prev;
- cap = NULL;
- prev = NULL;
- for (i = 0; i < n; i++) {
- cap = stgMallocBytes(sizeof(Capability), "initCapabilities");
- initCapability(cap);
- cap->link = prev;
- prev = cap;
- }
- free_capabilities = cap;
- rts_n_free_capabilities = n;
- IF_DEBUG(scheduler,
- sched_belch("allocated %d capabilities", rts_n_free_capabilities));
-}
-#endif /* SMP */
-
/* ---------------------------------------------------------------------------
* Function: initCapabilities()
*
initCapabilities( void )
{
#if defined(SMP)
- initCapabilities_(RtsFlags.ParFlags.nNodes);
+ nat i,n;
+
+ n = RtsFlags.ParFlags.nNodes;
+ capabilities = stgMallocBytes(n * sizeof(Capability), "initCapabilities");
+
+ for (i = 0; i < n; i++) {
+ initCapability(&capabilities[i]);
+ capabilities[i].link = &capabilities[i+1];
+ }
+ capabilities[n-1].link = NULL;
+
+ free_capabilities = &capabilities[0];
+ rts_n_free_capabilities = n;
+
+ IF_DEBUG(scheduler, sched_belch("allocated %d capabilities", n));
#else
- initCapability(&MainCapability);
+ capabilities = &MainCapability;
+ initCapability(&MainCapability);
+ rts_n_free_capabilities = 1;
#endif
#if defined(RTS_SUPPORTS_THREADS)
- initCondition(&returning_worker_cond);
- initCondition(&thread_ready_cond);
+ initCondition(&returning_worker_cond);
+ initCondition(&thread_ready_cond);
#endif
-
- rts_n_free_capabilities = 1;
}
/* ----------------------------------------------------------------------------
rts_n_free_capabilities = 0;
# endif
*cap = &MainCapability;
- handleSignalsInThisThread();
#endif
#if defined(RTS_SUPPORTS_THREADS)
IF_DEBUG(scheduler, sched_belch("worker: got capability"));
#if !defined(SMP)
ASSERT(rts_n_free_capabilities == 0);
#endif
+#if defined(SMP)
+ cap->link = free_capabilities;
+ free_capabilities = cap;
+#endif
// Check to see whether a worker thread can be given
// the go-ahead to return the result of an external call..
if (rts_n_waiting_workers > 0) {
// thread that is yielding its capability will repeatedly
// signal returning_worker_cond.
-#if defined(SMP)
- // SMP variant untested
- cap->link = free_capabilities;
- free_capabilities = cap;
-#endif
-
rts_n_waiting_workers--;
signalCondition(&returning_worker_cond);
IF_DEBUG(scheduler, sched_belch("worker: released capability to returning worker"));
} else {
signalCondition(passTarget);
}
- rts_n_free_capabilities = 1;
+ rts_n_free_capabilities++;
IF_DEBUG(scheduler, sched_belch("worker: released capability, passing it"));
} else {
-#if defined(SMP)
- cap->link = free_capabilities;
- free_capabilities = cap;
rts_n_free_capabilities++;
-#else
- rts_n_free_capabilities = 1;
-#endif
// Signal that a capability is available
if (rts_n_waiting_tasks > 0 && ANY_WORK_TO_DO()) {
signalCondition(&thread_ready_cond);
*pCap = &MainCapability;
ASSERT(rts_n_free_capabilities == 0);
#endif
- handleSignalsInThisThread();
} else {
grabCapability(pCap);
}
ToDo: should check whether the thread at the front of the queue is
bound, and if so wake up the appropriate worker.
-------------------------------------------------------------------------- */
-
void
threadRunnable ( void )
{
startSchedulerTaskIfNecessary();
#endif
}
+
+
+/* ----------------------------------------------------------------------------
+ prodWorker()
+
+ Wake up... time to die.
+ -------------------------------------------------------------------------- */
+void
+prodWorker ( void )
+{
+#if defined(RTS_SUPPORTS_THREADS)
+ signalCondition(&thread_ready_cond);
+#endif
+}