Mercurial > hg > release > icedtea7-forest-2.5 > hotspot
changeset 4816:c4a8806c0302
8012144: multiple SIGSEGVs fails on staxf
Summary: Missing fence in taskQueue lock-free code on some platforms
Reviewed-by: dholmes, kvn, shade, johnc, goetz
Contributed-by: Axel Siebenborn <axel.siebenborn@sap.com>
author | dholmes |
---|---|
date | Tue, 09 Jul 2013 21:05:44 -0400 |
parents | b29fc5f70d65 |
children | 0d7106aa7e08 |
files | src/share/vm/utilities/taskqueue.hpp |
diffstat | 1 files changed, 9 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/vm/utilities/taskqueue.hpp Thu Jul 04 03:38:59 2013 -0700 +++ b/src/share/vm/utilities/taskqueue.hpp Tue Jul 09 21:05:44 2013 -0400 @@ -391,7 +391,14 @@ template<class E, MEMFLAGS F, unsigned int N> bool GenericTaskQueue<E, F, N>::pop_global(E& t) { Age oldAge = _age.get(); - uint localBot = _bottom; + // Architectures with weak memory model require a fence here. The + // fence has a cumulative effect on getting age and getting bottom. + // This way it is guaranteed that bottom is not older than age, + // which is crucial for the correctness of the algorithm. +#if !(defined SPARC || defined IA32 || defined AMD64) + OrderAccess::fence(); +#endif + uint localBot = OrderAccess::load_acquire((volatile juint*)&_bottom); uint n_elems = size(localBot, oldAge.top()); if (n_elems == 0) { return false; @@ -677,7 +684,7 @@ template<class E, MEMFLAGS F, unsigned int N> inline bool GenericTaskQueue<E, F, N>::push(E t) { uint localBot = _bottom; - assert((localBot >= 0) && (localBot < N), "_bottom out of range."); + assert(localBot < N, "_bottom out of range."); idx_t top = _age.top(); uint dirty_n_elems = dirty_size(localBot, top); assert(dirty_n_elems < N, "n_elems out of range.");