#include "Rts.h"
#include "RtsUtils.h"
#include "RtsFlags.h"
+#include "STM.h"
#include "OSThreads.h"
#include "Capability.h"
#include "Schedule.h"
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;
}
/* ---------------------------------------------------------------------------
{
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;
}
- 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;
}