< 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 >