hotspot/src/share/vm/runtime/perfData.cpp
changeset 32614 b7b2407bc7e5
parent 27880 afb974a04396
child 33148 68fa8b6c4340
--- a/hotspot/src/share/vm/runtime/perfData.cpp	Wed Sep 02 17:49:46 2015 -0700
+++ b/hotspot/src/share/vm/runtime/perfData.cpp	Thu Sep 03 10:22:39 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,6 +39,7 @@
 PerfDataList*   PerfDataManager::_all = NULL;
 PerfDataList*   PerfDataManager::_sampled = NULL;
 PerfDataList*   PerfDataManager::_constants = NULL;
+volatile bool   PerfDataManager::_has_PerfData = 0;
 
 /*
  * The jvmstat global and subsystem jvmstat counter name spaces. The top
@@ -272,16 +273,22 @@
 }
 
 
-
-
-
-
 void PerfDataManager::destroy() {
 
   if (_all == NULL)
     // destroy already called, or initialization never happened
     return;
 
+  // Clear the flag before we free the PerfData counters. Thus begins
+  // the race between this thread and another thread that has just
+  // queried PerfDataManager::has_PerfData() and gotten back 'true'.
+  // The hope is that the other thread will finish its PerfData
+  // manipulation before we free the memory. The two alternatives are
+  // 1) leak the PerfData memory or 2) do some form of synchronized
+  // access or check before every PerfData operation.
+  _has_PerfData = false;
+  os::naked_short_sleep(1);  // 1ms sleep to let other thread(s) run
+
   for (int index = 0; index < _all->length(); index++) {
     PerfData* p = _all->at(index);
     delete p;
@@ -302,6 +309,7 @@
 
   if (_all == NULL) {
     _all = new PerfDataList(100);
+    _has_PerfData = true;
   }
 
   assert(!_all->contains(p->name()), "duplicate name added");