summaryrefslogtreecommitdiff
path: root/rts/HeapStackCheck.cmm
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2009-03-13 10:45:16 +0000
committerSimon Marlow <marlowsd@gmail.com>2009-03-13 10:45:16 +0000
commit304e7fb703e7afddc1ef9be6aab6505e36b63b06 (patch)
tree578332aa77e0c1c2d176218d23ae0beb0afd98af /rts/HeapStackCheck.cmm
parentc197fe602ed4aadf09affe0cdc18e7158d262012 (diff)
downloadhaskell-304e7fb703e7afddc1ef9be6aab6505e36b63b06.tar.gz
Instead of a separate context-switch flag, set HpLim to zero
This reduces the latency between a context-switch being triggered and the thread returning to the scheduler, which in turn should reduce the cost of the GC barrier when there are many cores. We still retain the old context_switch flag which is checked at the end of each block of allocation. The idea is that setting HpLim may fail if the the target thread is modifying HpLim at the same time; the context_switch flag is a fallback. It also allows us to "context switch soon" without forcing an immediate switch, which can be costly.
Diffstat (limited to 'rts/HeapStackCheck.cmm')
-rw-r--r--rts/HeapStackCheck.cmm11
1 files changed, 9 insertions, 2 deletions
diff --git a/rts/HeapStackCheck.cmm b/rts/HeapStackCheck.cmm
index 94cec387cc..10baca23c6 100644
--- a/rts/HeapStackCheck.cmm
+++ b/rts/HeapStackCheck.cmm
@@ -23,8 +23,11 @@ import LeaveCriticalSection;
*
* On discovering that a stack or heap check has failed, we do the following:
*
- * - If the context_switch flag is set, indicating that there are more
- * threads waiting to run, we yield to the scheduler
+ * - If HpLim==0, indicating that we should context-switch, we yield
+ * to the scheduler (return ThreadYielding).
+ *
+ * - If the context_switch flag is set (the backup plan if setting HpLim
+ * to 0 didn't trigger a context switch), we yield to the scheduler
* (return ThreadYielding).
*
* - If Hp > HpLim, we've had a heap check failure. This means we've
@@ -60,6 +63,10 @@ import LeaveCriticalSection;
#define GC_GENERIC \
DEBUG_ONLY(foreign "C" heapCheckFail()); \
if (Hp > HpLim) { \
+ if (HpLim == 0) { \
+ R1 = ThreadYielding; \
+ goto sched; \
+ } \
Hp = Hp - HpAlloc/*in bytes*/; \
if (HpAlloc <= BLOCK_SIZE \
&& bdescr_link(CurrentNursery) != NULL) { \