< prev index next >
src/hotspot/share/runtime/safepoint.cpp
Print this page
rev 47413 : Introduce SafepointMechanism
rev 47415 : Add Thread Local handshakes and thread local polling
*** 49,58 ****
--- 49,59 ----
#include "runtime/interfaceSupport.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/orderAccess.inline.hpp"
#include "runtime/osThread.hpp"
#include "runtime/safepoint.hpp"
+ #include "runtime/safepointMechanism.inline.hpp"
#include "runtime/signature.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/sweeper.hpp"
#include "runtime/synchronizer.hpp"
*** 178,203 ****
{
EventSafepointStateSynchronization sync_event;
int initial_running = 0;
_state = _synchronizing;
! OrderAccess::fence();
// Flush all thread states to memory
if (!UseMembar) {
os::serialize_thread_states();
}
// Make interpreter safepoint aware
Interpreter::notice_safepoints();
if (DeferPollingPageLoopCount < 0) {
// Make polling safepoint aware
guarantee (PageArmed == 0, "invariant") ;
PageArmed = 1 ;
os::make_polling_page_unreadable();
}
// Consider using active_processor_count() ... but that call is expensive.
int ncpus = os::processor_count() ;
#ifdef ASSERT
--- 179,215 ----
{
EventSafepointStateSynchronization sync_event;
int initial_running = 0;
_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()) {
! // 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
// Flush all thread states to memory
if (!UseMembar) {
os::serialize_thread_states();
}
+ if (SafepointMechanism::uses_global_page_poll()) {
// Make interpreter safepoint aware
Interpreter::notice_safepoints();
if (DeferPollingPageLoopCount < 0) {
// Make polling safepoint aware
guarantee (PageArmed == 0, "invariant") ;
PageArmed = 1 ;
os::make_polling_page_unreadable();
}
+ }
// Consider using active_processor_count() ... but that call is expensive.
int ncpus = os::processor_count() ;
#ifdef ASSERT
*** 302,312 ****
// Alternately, instead of counting iterations of the outer loop
// we could count the # of threads visited in the inner loop, above.
// 9. On windows consider using the return value from SwitchThreadTo()
// to drive subsequent spin/SwitchThreadTo()/Sleep(N) decisions.
! if (int(iterations) == DeferPollingPageLoopCount) {
guarantee (PageArmed == 0, "invariant") ;
PageArmed = 1 ;
os::make_polling_page_unreadable();
}
--- 314,324 ----
// Alternately, instead of counting iterations of the outer loop
// we could count the # of threads visited in the inner loop, above.
// 9. On windows consider using the return value from SwitchThreadTo()
// to drive subsequent spin/SwitchThreadTo()/Sleep(N) decisions.
! if (SafepointMechanism::uses_global_page_poll() && int(iterations) == DeferPollingPageLoopCount) {
guarantee (PageArmed == 0, "invariant") ;
PageArmed = 1 ;
os::make_polling_page_unreadable();
}
*** 452,491 ****
#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()) {
assert (!(cur->has_pending_exception() &&
cur->safepoint_state()->is_at_poll_safepoint()),
"safepoint installed a pending exception");
}
#endif // ASSERT
if (PageArmed) {
// Make polling safepoint aware
os::make_polling_page_readable();
PageArmed = 0 ;
}
// Remove safepoint check from interpreter
Interpreter::ignore_safepoints();
{
MutexLocker mu(Safepoint_lock);
assert(_state == _synchronized, "must be synchronized before ending safepoint synchronization");
// Set to not synchronized, so the threads will not go into the signal_thread_blocked method
// when they get restarted.
_state = _not_synchronized;
OrderAccess::fence();
log_debug(safepoint)("Leaving safepoint region");
// Start suspended threads
! for(JavaThread *current = Threads::first(); current; current = current->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.
--- 464,516 ----
#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()) {
assert (!(cur->has_pending_exception() &&
cur->safepoint_state()->is_at_poll_safepoint()),
"safepoint installed a pending exception");
}
#endif // ASSERT
if (PageArmed) {
+ assert(SafepointMechanism::uses_global_page_poll(), "sanity");
// Make polling safepoint aware
os::make_polling_page_readable();
PageArmed = 0 ;
}
+ if (SafepointMechanism::uses_global_page_poll()) {
// Remove safepoint check from interpreter
Interpreter::ignore_safepoints();
+ }
{
MutexLocker mu(Safepoint_lock);
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()) {
+ 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");
+ } else {
// Set to not synchronized, so the threads will not go into the signal_thread_blocked method
// when they get restarted.
_state = _not_synchronized;
OrderAccess::fence();
log_debug(safepoint)("Leaving safepoint region");
// Start suspended threads
! for (JavaThread *current = Threads::first(); current; current = current->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.
*** 501,510 ****
--- 526,536 ----
ThreadSafepointState* cur_state = current->safepoint_state();
assert(cur_state->type() != ThreadSafepointState::_running, "Thread not suspended at safepoint");
cur_state->restart();
assert(cur_state->is_running(), "safepoint state has not been reset");
}
+ }
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
*** 862,872 ****
--- 888,900 ----
void SafepointSynchronize::handle_polling_page_exception(JavaThread *thread) {
assert(thread->is_Java_thread(), "polling reference encountered by VM thread");
assert(thread->thread_state() == _thread_in_Java, "should come from Java code");
+ if (!ThreadLocalHandshakes) {
assert(SafepointSynchronize::is_synchronizing(), "polling encountered outside safepoint synchronization");
+ }
if (ShowSafepointMsgs) {
tty->print("handle_polling_page_exception: ");
}
*** 894,904 ****
}
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()) {
cur_state = cur_thread->safepoint_state();
if (cur_thread->thread_state() != _thread_blocked &&
((reason == _spinning_timeout && cur_state->is_running()) ||
--- 922,932 ----
}
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()) {
cur_state = cur_thread->safepoint_state();
if (cur_thread->thread_state() != _thread_blocked &&
((reason == _spinning_timeout && cur_state->is_running()) ||
*** 1060,1076 ****
_thread->print_thread_state_on(st);
}
// ---------------------------------------------------------------------------------------------------------------------
! // Block the thread at the safepoint poll or poll return.
void ThreadSafepointState::handle_polling_page_exception() {
// Check state. block() will set thread state to thread_in_vm which will
// cause the safepoint state _type to become _call_back.
! assert(type() == ThreadSafepointState::_running,
! "polling page exception on thread not running state");
// Step 1: Find the nmethod from the return address
if (ShowSafepointMsgs && Verbose) {
tty->print_cr("Polling page exception at " INTPTR_FORMAT, p2i(thread()->saved_exception_pc()));
}
--- 1088,1105 ----
_thread->print_thread_state_on(st);
}
// ---------------------------------------------------------------------------------------------------------------------
! // Block the thread at poll or poll return for safepoint/handshake.
void ThreadSafepointState::handle_polling_page_exception() {
// Check state. block() will set thread state to thread_in_vm which will
// cause the safepoint state _type to become _call_back.
! suspend_type t = type();
! assert(!SafepointMechanism::uses_global_page_poll() || t == ThreadSafepointState::_running,
! "polling page exception on thread not running state: %u", uint(t));
// Step 1: Find the nmethod from the return address
if (ShowSafepointMsgs && Verbose) {
tty->print_cr("Polling page exception at " INTPTR_FORMAT, p2i(thread()->saved_exception_pc()));
}
*** 1108,1118 ****
return_value = Handle(thread(), result);
assert(Universe::heap()->is_in_or_null(result), "must be heap pointer");
}
// Block the thread
! SafepointSynchronize::block(thread());
// restore oop result, if any
if (return_oop) {
caller_fr.set_saved_oop_result(&map, return_value());
}
--- 1137,1147 ----
return_value = Handle(thread(), result);
assert(Universe::heap()->is_in_or_null(result), "must be heap pointer");
}
// Block the thread
! SafepointMechanism::block_if_requested(thread());
// restore oop result, if any
if (return_oop) {
caller_fr.set_saved_oop_result(&map, return_value());
}
*** 1124,1134 ****
// verify the blob built the "return address" correctly
assert(real_return_addr == caller_fr.pc(), "must match");
// Block the thread
! SafepointSynchronize::block(thread());
set_at_poll_safepoint(false);
// If we have a pending async exception deoptimize the frame
// as otherwise we may never deliver it.
if (thread()->has_async_condition()) {
--- 1153,1163 ----
// verify the blob built the "return address" correctly
assert(real_return_addr == caller_fr.pc(), "must match");
// Block the thread
! SafepointMechanism::block_if_requested(thread());
set_at_poll_safepoint(false);
// If we have a pending async exception deoptimize the frame
// as otherwise we may never deliver it.
if (thread()->has_async_condition()) {
*** 1405,1415 ****
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()) {
cur->safepoint_state()->print();
}
}
}
--- 1434,1444 ----
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()) {
cur->safepoint_state()->print();
}
}
}
< prev index next >