< prev index next >

src/hotspot/share/runtime/safepoint.cpp

Print this page
rev 47862 : imported patch 10.07.open.rebase_20171110.dcubed
rev 47863 : imported patch 10.08.open.rebase_20171114.rehn

@@ -57,10 +57,11 @@
 #include "runtime/stubCodeGenerator.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "runtime/sweeper.hpp"
 #include "runtime/synchronizer.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/threadSMR.hpp"
 #include "runtime/timerTrace.hpp"
 #include "services/runtimeService.hpp"
 #include "trace/tracing.hpp"
 #include "trace/traceMacros.hpp"
 #include "utilities/events.hpp"

@@ -172,11 +173,11 @@
     _state            = _synchronizing;
 
     if (SafepointMechanism::uses_thread_local_poll()) {
       // Arming the per thread poll while having _state != _not_synchronized means safepointing
       log_trace(safepoint)("Setting thread local yield flag for threads");
-      for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
+      for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur = jtiwh.next(); ) {
         // Make sure the threads start polling, it is time to yield.
         SafepointMechanism::arm_local_poll(cur); // release store, global state -> local state
       }
     }
     OrderAccess::fence(); // storestore|storeload, global state -> local state

@@ -198,13 +199,16 @@
       }
     }
 
     // Consider using active_processor_count() ... but that call is expensive.
     int ncpus = os::processor_count() ;
+    unsigned int iterations = 0;
 
+    {
+      JavaThreadIteratorWithHandle jtiwh;
 #ifdef ASSERT
-    for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
+      for (; JavaThread *cur = jtiwh.next(); ) {
       assert(cur->safepoint_state()->is_running(), "Illegal initial state");
       // Clear the visited flag to ensure that the critical counts are collected properly.
       cur->set_visited_for_critical_count(false);
     }
 #endif // ASSERT

@@ -211,14 +215,14 @@
 
     if (SafepointTimeout)
       safepoint_limit_time = os::javaTimeNanos() + (jlong)SafepointTimeoutDelay * MICROUNITS;
 
     // Iterate through all threads until it have been determined how to stop them all at a safepoint
-    unsigned int iterations = 0;
     int steps = 0 ;
     while(still_running > 0) {
-      for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
+        jtiwh.rewind();
+        for (; JavaThread *cur = jtiwh.next(); ) {
         assert(!cur->is_ConcurrentGC_thread(), "A concurrent GC thread is unexpectly being suspended");
         ThreadSafepointState *cur_state = cur->safepoint_state();
         if (cur_state->is_running()) {
           cur_state->examine_state_of_thread();
           if (!cur_state->is_running()) {

@@ -325,10 +329,11 @@
 
         iterations ++ ;
       }
       assert(iterations < (uint)max_jint, "We have been iterating in the safepoint loop too long");
     }
+    } // ThreadsListHandle destroyed here.
     assert(still_running == 0, "sanity check");
 
     if (PrintSafepointStatistics) {
       update_statistics_on_spin_end();
     }

@@ -339,11 +344,11 @@
       sync_event.set_initialThreadCount(initial_running);
       sync_event.set_runningThreadCount(_waiting_to_block);
       sync_event.set_iterations(iterations);
       sync_event.commit();
     }
-  } //EventSafepointStateSync
+  } // EventSafepointStateSynchronization destroyed here.
 
   // wait until all threads are stopped
   {
     EventSafepointWaitBlocked wait_blocked_event;
     int initial_waiting_to_block = _waiting_to_block;

@@ -391,12 +396,12 @@
       wait_blocked_event.commit();
     }
   } // EventSafepointWaitBlocked
 
 #ifdef ASSERT
-  for (JavaThread *cur = Threads::first(); cur != NULL; cur = cur->next()) {
-    // make sure all the threads were visited
+  // Make sure all the threads were visited.
+  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur = jtiwh.next(); ) {
     assert(cur->was_visited_for_critical_count(), "missed a thread");
   }
 #endif // ASSERT
 
   // Update the count of active JNI critical regions

@@ -450,15 +455,17 @@
 
   if (PrintSafepointStatistics) {
     end_statistics(os::javaTimeNanos());
   }
 
+  {
+    JavaThreadIteratorWithHandle jtiwh;
 #ifdef ASSERT
   // A pending_exception cannot be installed during a safepoint.  The threads
   // may install an async exception after they come back from a safepoint into
   // pending_exception after they unblock.  But that should happen later.
-  for (JavaThread *cur = Threads::first(); cur; cur = cur->next()) {
+    for (; JavaThread *cur = jtiwh.next(); ) {
     assert (!(cur->has_pending_exception() &&
               cur->safepoint_state()->is_at_poll_safepoint()),
             "safepoint installed a pending exception");
   }
 #endif // ASSERT

@@ -481,11 +488,12 @@
     assert(_state == _synchronized, "must be synchronized before ending safepoint synchronization");
 
     if (SafepointMechanism::uses_thread_local_poll()) {
       _state = _not_synchronized;
       OrderAccess::storestore(); // global state -> local state
-      for (JavaThread *current = Threads::first(); current; current = current->next()) {
+        jtiwh.rewind();
+        for (; JavaThread *current = jtiwh.next(); ) {
         ThreadSafepointState* cur_state = current->safepoint_state();
         cur_state->restart(); // TSS _running
         SafepointMechanism::disarm_local_poll(current); // release store, local state -> polling page
       }
       log_debug(safepoint)("Leaving safepoint region");

@@ -496,11 +504,12 @@
       OrderAccess::fence();
 
       log_debug(safepoint)("Leaving safepoint region");
 
       // Start suspended threads
-      for (JavaThread *current = Threads::first(); current; current = current->next()) {
+        jtiwh.rewind();
+        for (; JavaThread *current = jtiwh.next(); ) {
         // A problem occurring on Solaris is when attempting to restart threads
         // the first #cpus - 1 go well, but then the VMThread is preempted when we get
         // to the next one (since it has been running the longest).  We then have
         // to wait for a cpu to become available before we can continue restarting
         // threads.

@@ -520,15 +529,16 @@
       }
     }
 
     RuntimeService::record_safepoint_end();
 
-    // Release threads lock, so threads can be created/destroyed again. It will also starts all threads
-    // blocked in signal_thread_blocked
+      // Release threads lock, so threads can be created/destroyed again.
+      // It will also release all threads blocked in signal_thread_blocked.
     Threads_lock->unlock();
-
   }
+  } // ThreadsListHandle destroyed here.
+
   Universe::heap()->safepoint_synchronize_end();
   // record this time so VMThread can keep track how much time has elapsed
   // since last safepoint.
   _end_of_last_safepoint = os::javaTimeMillis();
 

@@ -913,12 +923,11 @@
     }
 
     tty->print_cr("# SafepointSynchronize::begin: Threads which did not reach the safepoint:");
     ThreadSafepointState *cur_state;
     ResourceMark rm;
-    for (JavaThread *cur_thread = Threads::first(); cur_thread;
-        cur_thread = cur_thread->next()) {
+    for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur_thread = jtiwh.next(); ) {
       cur_state = cur_thread->safepoint_state();
 
       if (cur_thread->thread_state() != _thread_blocked &&
           ((reason == _spinning_timeout && cur_state->is_running()) ||
            (reason == _blocking_timeout && !cur_state->has_called_back()))) {

@@ -1425,11 +1434,11 @@
     tty->print_cr("not synchronized");
   } else if (_state == _synchronizing || _state == _synchronized) {
     tty->print_cr("State: %s", (_state == _synchronizing) ? "synchronizing" :
                   "synchronized");
 
-    for (JavaThread *cur = Threads::first(); cur; cur = cur->next()) {
+    for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur = jtiwh.next(); ) {
        cur->safepoint_state()->print();
     }
   }
 }
 
< prev index next >