summaryrefslogtreecommitdiff
path: root/rts/ThreadPaused.c
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2009-11-25 12:59:17 +0000
committerSimon Marlow <marlowsd@gmail.com>2009-11-25 12:59:17 +0000
commitd2c874dc74e2d99eda70d83e9b540f54c45c2154 (patch)
tree0a5db339727ea1557e7cc1205cda0cc1d327c7f8 /rts/ThreadPaused.c
parent69ba3e6bbae81ce02f6ea66d0686667b7dfb7e8f (diff)
downloadhaskell-d2c874dc74e2d99eda70d83e9b540f54c45c2154.tar.gz
threadStackOverflow: check whether stack squeezing released some stack (#3677)
In a stack overflow situation, stack squeezing may reduce the stack size, but we don't know whether it has been reduced enough for the stack check to succeed if we try again. Fortunately stack squeezing is idempotent, so all we need to do is record whether *any* squeezing happened. If we are at the stack's absolute -K limit, and stack squeezing happened, then we try running the thread again. We also want to avoid enlarging the stack if squeezing has already released some of it. However, we don't want to get into a pathalogical situation where a thread has a nearly full stack (near its current limit, but not near the absolute -K limit), keeps allocating a little bit, squeezing removes a little bit, and then it runs again. So to avoid this, if we squeezed *and* there is still less than BLOCK_SIZE_W words free, then we enlarge the stack anyway.
Diffstat (limited to 'rts/ThreadPaused.c')
-rw-r--r--rts/ThreadPaused.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/rts/ThreadPaused.c b/rts/ThreadPaused.c
index 58c30e330e..96a23673a7 100644
--- a/rts/ThreadPaused.c
+++ b/rts/ThreadPaused.c
@@ -317,5 +317,10 @@ end:
if (RtsFlags.GcFlags.squeezeUpdFrames == rtsTrue &&
((weight <= 5 && words_to_squeeze > 0) || weight < words_to_squeeze)) {
stackSqueeze(tso, (StgPtr)frame);
+ tso->flags |= TSO_SQUEEZED;
+ // This flag tells threadStackOverflow() that the stack was
+ // squeezed, because it may not need to be expanded.
+ } else {
+ tso->flags &= ~TSO_SQUEEZED;
}
}