changeset 4625: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.");