diff options
author | Adam Gundry <adam@well-typed.com> | 2014-11-18 10:17:22 +0000 |
---|---|---|
committer | Adam Gundry <adam@well-typed.com> | 2014-11-18 10:17:22 +0000 |
commit | 7b24febb2afc92289846a1ff7593d9a4ae2b61d1 (patch) | |
tree | 218fb067524582677b40ced852d2c2808885c1df /rts/Schedule.c | |
parent | c0f657fd2549719b2959dbf93fcd744c02427a5c (diff) | |
parent | b9096df6a9733e38e15361e79973ef5659fc5c22 (diff) | |
download | haskell-wip/tc-plugins-amg.tar.gz |
Merge remote-tracking branch 'origin/master' into wip/tc-plugins-amgwip/tc-plugins-amg
Diffstat (limited to 'rts/Schedule.c')
-rw-r--r-- | rts/Schedule.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/rts/Schedule.c b/rts/Schedule.c index b11270832d..e9b0289599 100644 --- a/rts/Schedule.c +++ b/rts/Schedule.c @@ -481,6 +481,10 @@ run_thread: // happened. So find the new location: t = cap->r.rCurrentTSO; + // cap->r.rCurrentTSO is charged for calls to allocate(), so we + // don't want it set when not running a Haskell thread. + cap->r.rCurrentTSO = NULL; + // And save the current errno in this thread. // XXX: possibly bogus for SMP because this thread might already // be running again, see code below. @@ -1078,6 +1082,21 @@ schedulePostRunThread (Capability *cap, StgTSO *t) } } + // + // If the current thread's allocation limit has run out, send it + // the AllocationLimitExceeded exception. + + if (t->alloc_limit < 0 && (t->flags & TSO_ALLOC_LIMIT)) { + // Use a throwToSelf rather than a throwToSingleThreaded, because + // it correctly handles the case where the thread is currently + // inside mask. Also the thread might be blocked (e.g. on an + // MVar), and throwToSingleThreaded doesn't unblock it + // correctly in that case. + throwToSelf(cap, t, allocationLimitExceeded_closure); + t->alloc_limit = (StgInt64)RtsFlags.GcFlags.allocLimitGrace + * BLOCK_SIZE; + } + /* some statistics gathering in the parallel case */ } @@ -2214,6 +2233,9 @@ suspendThread (StgRegTable *reg, rtsBool interruptible) task->incall->suspended_tso = tso; task->incall->suspended_cap = cap; + // Otherwise allocate() will write to invalid memory. + cap->r.rCurrentTSO = NULL + ACQUIRE_LOCK(&cap->lock); suspendTask(cap,task); |