#include "PosixSource.h"
#include "Rts.h"
+
+#include "sm/Storage.h"
#include "Threads.h"
#include "Trace.h"
#include "RaiseAsync.h"
-#include "SMP.h"
#include "Schedule.h"
-#include "LdvProfile.h"
#include "Updates.h"
#include "STM.h"
#include "Sanity.h"
(unsigned long)source->id, (unsigned long)target->id);
#ifdef DEBUG
- if (traceClass(DEBUG_sched)) {
- debugTraceBegin("throwTo: target");
- printThreadStatus(target);
- debugTraceEnd();
- }
+ traceThreadStatus(DEBUG_sched, target);
#endif
goto check_target;
}
done:
- tso->_link = END_TSO_QUEUE; // no write barrier reqd
- tso->why_blocked = NotBlocked;
- tso->block_info.closure = NULL;
- appendToRunQueue(cap,tso);
-
- // We might have just migrated this TSO to our Capability:
- if (tso->bound) {
- tso->bound->cap = cap;
- }
- tso->cap = cap;
+ unblockOne(cap, tso);
}
/* -----------------------------------------------------------------------------
#if defined(PROFILING)
/*
* Debugging tool: on raising an exception, show where we are.
- * See also Exception.cmm:raisezh_fast.
+ * See also Exception.cmm:stg_raisezh.
* This wasn't done for asynchronous exceptions originally; see #1450
*/
if (RtsFlags.ProfFlags.showCCSOnException)
if (stop_at_atomically) {
ASSERT(stmGetEnclosingTRec(tso->trec) == NO_TREC);
stmCondemnTransaction(cap, tso -> trec);
- tso->sp = frame;
+ tso->sp = frame - 2;
+ // The ATOMICALLY_FRAME expects to be returned a
+ // result from the transaction, which it stores in the
+ // stack frame. Hence we arrange to return a dummy
+ // result, so that the GC doesn't get upset (#3578).
+ // Perhaps a better way would be to have a different
+ // ATOMICALLY_FRAME instance for condemned
+ // transactions, but I don't fully understand the
+ // interaction with STM invariants.
+ tso->sp[1] = (W_)&stg_NO_TREC_closure;
+ tso->sp[0] = (W_)&stg_gc_unpt_r1_info;
tso->what_next = ThreadRunGHC;
return;
}