#endif
#include "Trace.h"
#include "RetainerProfile.h"
+#include "RaiseAsync.h"
#include <string.h>
copied += mut_list_size;
debugTrace(DEBUG_gc,
- "mut_list_size: %ld (%d vars, %d arrays, %d others)",
- mut_list_size * sizeof(W_),
+ "mut_list_size: %lu (%d vars, %d arrays, %d others)",
+ (unsigned long)(mut_list_size * sizeof(W_)),
mutlist_MUTVARS, mutlist_MUTARRS, mutlist_OTHERS);
}
}
return q;
- case CONSTR_INTLIKE:
- case CONSTR_CHARLIKE:
case CONSTR_NOCAF_STATIC:
/* no need to put these on the static linked list, they don't need
* to be scavenged.
) {
tso->block_info.closure = evacuate(tso->block_info.closure);
}
- if ( tso->blocked_exceptions != NULL ) {
- tso->blocked_exceptions =
- (StgTSO *)evacuate((StgClosure *)tso->blocked_exceptions);
- }
+ tso->blocked_exceptions =
+ (StgTSO *)evacuate((StgClosure *)tso->blocked_exceptions);
// We don't always chase the link field: TSOs on the blackhole
// queue are not automatically alive, so the link field is a
nat weight_pending = 0;
rtsBool prev_was_update_frame;
+ // Check to see whether we have threads waiting to raise
+ // exceptions, and we're not blocking exceptions, or are blocked
+ // interruptibly. This is important; if a thread is running with
+ // TSO_BLOCKEX and becomes blocked interruptibly, this is the only
+ // place we ensure that the blocked_exceptions get a chance.
+ maybePerformBlockedException (cap, tso);
+ if (tso->what_next == ThreadKilled) { return; }
+
stack_end = &tso->stack[tso->stack_size];
frame = (StgClosure *)tso->sp;
if (closure_IND(bh) || bh->header.info == &stg_BLACKHOLE_info) {
debugTrace(DEBUG_squeeze,
"suspending duplicate work: %ld words of stack",
- (StgPtr)frame - tso->sp);
+ (long)((StgPtr)frame - tso->sp));
// If this closure is already an indirection, then
// suspend the computation up to this point: