diff options
author | Simon Marlow <marlowsd@gmail.com> | 2015-06-19 14:41:32 +0100 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2015-06-26 09:25:35 +0100 |
commit | be0ce8718ea40b091e69dd48fe6bc62b6b551154 (patch) | |
tree | 85214870fd2ff24890158b7c92de914dc68d21bb | |
parent | 0aaea5b8345fc4b061b97df8bcaa7c6b07594719 (diff) | |
download | haskell-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.c | 18 |
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. |