From e7c88ca74c8e8abc77b0a3d4786273067ec79b68 Mon Sep 17 00:00:00 2001
Date: Fri, 22 Jan 2021 15:23:03 +0800
Subject: 8165860: WorkGroup classes are missing volatile
 specifiers for lock-free code

Summary: <gc>: WorkGroup classes are missing volatile specifiers for lock-free code
LLT: NA
Bug url: https://bugs.openjdk.java.net/browse/JDK-8165860
---
 hotspot/src/share/vm/utilities/workgroup.cpp | 12 +++++-------
 hotspot/src/share/vm/utilities/workgroup.hpp |  8 ++++----
 2 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/hotspot/src/share/vm/utilities/workgroup.cpp b/hotspot/src/share/vm/utilities/workgroup.cpp
index 08b97aa77..29c7a7bf5 100644
--- a/hotspot/src/share/vm/utilities/workgroup.cpp
+++ b/hotspot/src/share/vm/utilities/workgroup.cpp
@@ -502,23 +502,21 @@ bool SequentialSubTasksDone::valid() {
 }
 
 bool SequentialSubTasksDone::is_task_claimed(uint& t) {
-  uint* n_claimed_ptr = &_n_claimed;
-  t = *n_claimed_ptr;
+  t = _n_claimed;
   while (t < _n_tasks) {
-    jint res = Atomic::cmpxchg(t+1, n_claimed_ptr, t);
+    jint res = Atomic::cmpxchg(t+1, &_n_claimed, t);
     if (res == (jint)t) {
       return false;
     }
-    t = *n_claimed_ptr;
+    t = res;
   }
   return true;
 }
 
 bool SequentialSubTasksDone::all_tasks_completed() {
-  uint* n_completed_ptr = &_n_completed;
-  uint  complete        = *n_completed_ptr;
+  uint  complete        = _n_completed;
   while (true) {
-    uint res = Atomic::cmpxchg(complete+1, n_completed_ptr, complete);
+    uint res = Atomic::cmpxchg(complete+1, &_n_completed, complete);
     if (res == complete) {
       break;
     }
diff --git a/hotspot/src/share/vm/utilities/workgroup.hpp b/hotspot/src/share/vm/utilities/workgroup.hpp
index 30337f1ef..ef2dff493 100644
--- a/hotspot/src/share/vm/utilities/workgroup.hpp
+++ b/hotspot/src/share/vm/utilities/workgroup.hpp
@@ -400,7 +400,7 @@ public:
 // enumeration type.
 
 class SubTasksDone: public CHeapObj<mtInternal> {
-  uint* _tasks;
+  volatile uint* _tasks;
   uint _n_tasks;
   // _n_threads is used to determine when a sub task is done.
   // It does not control how many threads will execute the subtask
@@ -408,7 +408,7 @@ class SubTasksDone: public CHeapObj<mtInternal> {
   // in order to correctly decide when the subtask is done (all the
   // threads working on the task have finished).
   uint _n_threads;
-  uint _threads_completed;
+  volatile uint _threads_completed;
 #ifdef ASSERT
   volatile uint _claimed;
 #endif
@@ -454,11 +454,11 @@ public:
 class SequentialSubTasksDone : public StackObj {
 protected:
   uint _n_tasks;     // Total number of tasks available.
-  uint _n_claimed;   // Number of tasks claimed.
+  volatile uint _n_claimed;   // Number of tasks claimed.
   // _n_threads is used to determine when a sub task is done.
   // See comments on SubTasksDone::_n_threads
   uint _n_threads;   // Total number of parallel threads.
-  uint _n_completed; // Number of completed threads.
+  volatile uint _n_completed; // Number of completed threads.
 
   void clear();
 
-- 
2.19.0

