/* ---------------------------------------------------------------------------
*
- * (c) The GHC Team, 2003-2005
+ * (c) The GHC Team, 2003-2006
*
* Capabilities
*
#include "Rts.h"
#include "RtsUtils.h"
#include "RtsFlags.h"
+#include "STM.h"
#include "OSThreads.h"
#include "Capability.h"
#include "Schedule.h"
// locking, so we don't do that.
Capability *last_free_capability;
-#ifdef SMP
-#define UNUSED_IF_NOT_SMP
-#else
-#define UNUSED_IF_NOT_SMP STG_UNUSED
-#endif
-
-#ifdef RTS_USER_SIGNALS
-#define UNUSED_IF_NOT_THREADS
-#else
-#define UNUSED_IF_NOT_THREADS STG_UNUSED
-#endif
-
-
+#if defined(THREADED_RTS)
STATIC_INLINE rtsBool
globalWorkToDo (void)
{
return blackholes_need_checking
|| interrupted
-#if defined(RTS_USER_SIGNALS)
- || signals_pending()
-#endif
;
}
+#endif
#if defined(THREADED_RTS)
STATIC_INLINE rtsBool
for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
cap->mut_lists[g] = NULL;
}
+
+ cap->free_tvar_wait_queues = END_STM_WAIT_QUEUE;
+ cap->free_trec_chunks = END_STM_CHUNK_LIST;
+ cap->free_trec_headers = NO_TREC;
+ cap->transaction_tokens = 0;
}
/* ---------------------------------------------------------------------------
#if defined(THREADED_RTS)
STATIC_INLINE void
-giveCapabilityToTask (Capability *cap, Task *task)
+giveCapabilityToTask (Capability *cap USED_IF_DEBUG, Task *task)
{
ASSERT_LOCK_HELD(&cap->lock);
ASSERT(task->cap == cap);
- // We are not modifying task->cap, so we do not need to take task->lock.
IF_DEBUG(scheduler,
sched_belch("passing capability %d to %s %p",
cap->no, task->tso ? "bound task" : "worker",
task = cap->running_task;
- ASSERT_CAPABILITY_INVARIANTS(cap,task);
+ ASSERT_PARTIAL_CAPABILITY_INVARIANTS(cap,task);
cap->running_task = NULL;
}
void
-releaseCapability (Capability* cap UNUSED_IF_NOT_THREADS)
+releaseCapability (Capability* cap USED_IF_THREADS)
{
ACQUIRE_LOCK(&cap->lock);
releaseCapability_(cap);
}
static void
-releaseCapabilityAndQueueWorker (Capability* cap UNUSED_IF_NOT_THREADS)
+releaseCapabilityAndQueueWorker (Capability* cap USED_IF_THREADS)
{
Task *task;
*
* ------------------------------------------------------------------------- */
void
-waitForReturnCapability (Capability **pCap,
- Task *task UNUSED_IF_NOT_THREADS)
+waitForReturnCapability (Capability **pCap, Task *task)
{
#if !defined(THREADED_RTS)
}
- ASSERT_CAPABILITY_INVARIANTS(cap,task);
+ ASSERT_FULL_CAPABILITY_INVARIANTS(cap,task);
IF_DEBUG(scheduler,
sched_belch("returning; got capability %d", cap->no));
{
Capability *cap = *pCap;
- // The fast path; no locking
- if ( cap->returning_tasks_hd == NULL && anyWorkForMe(cap,task) )
- return;
+ // The fast path has no locking, if we don't enter this while loop
while ( cap->returning_tasks_hd != NULL || !anyWorkForMe(cap,task) ) {
IF_DEBUG(scheduler, sched_belch("giving up capability %d", cap->no));
// We must now release the capability and wait to be woken up
// again.
+ task->wakeup = rtsFalse;
releaseCapabilityAndQueueWorker(cap);
for (;;) {
IF_DEBUG(scheduler, sched_belch("woken up on capability %d", cap->no));
ACQUIRE_LOCK(&cap->lock);
if (cap->running_task != NULL) {
+ IF_DEBUG(scheduler, sched_belch("capability %d is owned by another task", cap->no));
RELEASE_LOCK(&cap->lock);
continue;
}
*pCap = cap;
- ASSERT_CAPABILITY_INVARIANTS(cap,task);
+ ASSERT_FULL_CAPABILITY_INVARIANTS(cap,task);
return;
}