summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2015-06-19 14:41:32 +0100
committerSimon Marlow <marlowsd@gmail.com>2015-06-26 09:25:35 +0100
commitbe0ce8718ea40b091e69dd48fe6bc62b6b551154 (patch)
tree85214870fd2ff24890158b7c92de914dc68d21bb
parent0aaea5b8345fc4b061b97df8bcaa7c6b07594719 (diff)
downloadhaskell-be0ce8718ea40b091e69dd48fe6bc62b6b551154.tar.gz
Fix for crash in setnumcapabilities001
getNewNursery() was unconditionally incrementing next_nursery, which is normally fine but it broke an assumption in storageAddCapabilities(). This manifested as an occasional crash in the setnumcapabilities001 test.
-rw-r--r--rts/sm/Storage.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c
index 77796013ce..6e9b0634b7 100644
--- a/rts/sm/Storage.c
+++ b/rts/sm/Storage.c
@@ -576,6 +576,7 @@ allocNursery (bdescr *tail, W_ blocks)
STATIC_INLINE void
assignNurseryToCapability (Capability *cap, nat n)
{
+ ASSERT(n < n_nurseries);
cap->r.rNursery = &nurseries[n];
cap->r.rCurrentNursery = nurseries[n].blocks;
newNurseryBlock(nurseries[n].blocks);
@@ -726,14 +727,19 @@ resizeNurseries (W_ blocks)
rtsBool
getNewNursery (Capability *cap)
{
- StgWord i = atomic_inc(&next_nursery, 1) - 1;
- if (i >= n_nurseries) {
- return rtsFalse;
+ StgWord i;
+
+ for(;;) {
+ i = next_nursery;
+ if (i >= n_nurseries) {
+ return rtsFalse;
+ }
+ if (cas(&next_nursery, i, i+1) == i) {
+ assignNurseryToCapability(cap, i);
+ return rtsTrue;
+ }
}
- assignNurseryToCapability(cap, i);
- return rtsTrue;
}
-
/* -----------------------------------------------------------------------------
move_STACK is called to update the TSO structure after it has been
moved from one place to another.