< prev index next >

src/hotspot/share/runtime/synchronizer.cpp

Print this page
rev 59757 : Add whitebox support for deflating idle monitors including ObjectSynchronizer::request_deflate_idle_monitors(); drop ObjectSynchronizer::_is_special_deflation_requested flag, functions and uses; switch to ObjectSynchronizer::request_deflate_idle_monitors() as needed; _last_async_deflation_time_ns should be set at the end of async deflation;

*** 119,129 **** static volatile intptr_t gInflationLocks[NINFLATIONLOCKS]; // global list of blocks of monitors PaddedObjectMonitor* ObjectSynchronizer::g_block_list = NULL; bool volatile ObjectSynchronizer::_is_async_deflation_requested = false; - bool volatile ObjectSynchronizer::_is_special_deflation_requested = false; jlong ObjectSynchronizer::_last_async_deflation_time_ns = 0; struct ObjectMonitorListGlobals { char _pad_prefix[OM_CACHE_LINE_SIZE]; // These are highly shared list related variables. --- 119,128 ----
*** 1307,1317 **** monitors_used_above_threshold()) { // It's been longer than our specified deflate interval and there // are too many monitors in use. We don't deflate more frequently // than AsyncDeflationInterval (unless is_async_deflation_requested) // in order to not swamp the ServiceThread. - _last_async_deflation_time_ns = os::javaTimeNanos(); return true; } return false; } --- 1306,1315 ----
*** 1321,1340 **** // Too many monitors in use. return true; } return false; } - if (is_special_deflation_requested()) { - // For AsyncDeflateIdleMonitors only do a safepoint deflation - // if there is a special deflation request. - return true; - } return false; } jlong ObjectSynchronizer::time_since_last_async_deflation_ms() { ! return (os::javaTimeNanos() - _last_async_deflation_time_ns) / (NANOUNITS / MILLIUNITS); } void ObjectSynchronizer::oops_do(OopClosure* f) { // We only scan the global used list here (for moribund threads), and // the thread-local monitors in Thread::oops_do(). --- 1319,1373 ---- // Too many monitors in use. return true; } return false; } return false; } + bool ObjectSynchronizer::request_deflate_idle_monitors() { + bool is_JavaThread = Thread::current()->is_Java_thread(); + bool ret_code = false; + + if (AsyncDeflateIdleMonitors) { + jlong last_time = last_async_deflation_time_ns(); + set_is_async_deflation_requested(true); + { + MonitorLocker ml(Service_lock, Mutex::_no_safepoint_check_flag); + ml.notify_all(); + } + const int N_CHECKS = 5; + for (int i = 0; i < N_CHECKS; i++) { // sleep for at most 5 seconds + if (last_async_deflation_time_ns() > last_time) { + log_info(monitorinflation)("Async Deflation happened after %d check(s).", i); + ret_code = true; + break; + } + if (is_JavaThread) { + // JavaThread has to honor the blocking protocol. + ThreadBlockInVM tbivm(JavaThread::current()); + os::naked_short_sleep(999); // sleep for almost 1 second + } else { + os::naked_short_sleep(999); // sleep for almost 1 second + } + } + if (ret_code == false) { + log_info(monitorinflation)("Async Deflation DID NOT happen after %d checks.", N_CHECKS); + } + } else if (!Thread::current()->is_VM_thread()) { + // The VMThread only calls this at shutdown time before the final + // safepoint so it should not need to force this safepoint. + VM_ForceSafepoint force_safepoint_op; + VMThread::execute(&force_safepoint_op); + ret_code = true; + } + + return ret_code; + } + jlong ObjectSynchronizer::time_since_last_async_deflation_ms() { ! return (os::javaTimeNanos() - last_async_deflation_time_ns()) / (NANOUNITS / MILLIUNITS); } void ObjectSynchronizer::oops_do(OopClosure* f) { // We only scan the global used list here (for moribund threads), and // the thread-local monitors in Thread::oops_do().
*** 2015,2027 **** assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); // The per-thread in-use lists are handled in // ParallelSPCleanupThreadClosure::do_thread(). ! if (!AsyncDeflateIdleMonitors || is_special_deflation_requested()) { ! // Use the older mechanism for the global in-use list or if a ! // special deflation has been requested before the safepoint. ObjectSynchronizer::deflate_idle_monitors(counters); return; } log_debug(monitorinflation)("requesting async deflation of idle monitors."); --- 2048,2059 ---- assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); // The per-thread in-use lists are handled in // ParallelSPCleanupThreadClosure::do_thread(). ! if (!AsyncDeflateIdleMonitors) { ! // Use the older mechanism for the global in-use list. ObjectSynchronizer::deflate_idle_monitors(counters); return; } log_debug(monitorinflation)("requesting async deflation of idle monitors.");
*** 2436,2450 **** void ObjectSynchronizer::deflate_idle_monitors(DeflateMonitorCounters* counters) { assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); if (AsyncDeflateIdleMonitors) { // Nothing to do when global idle ObjectMonitors are deflated using ! // a JavaThread unless a special deflation has been requested. ! if (!is_special_deflation_requested()) { return; } - } bool deflated = false; ObjectMonitor* free_head_p = NULL; // Local SLL of scavenged monitors ObjectMonitor* free_tail_p = NULL; --- 2468,2480 ---- void ObjectSynchronizer::deflate_idle_monitors(DeflateMonitorCounters* counters) { assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); if (AsyncDeflateIdleMonitors) { // Nothing to do when global idle ObjectMonitors are deflated using ! // a JavaThread. return; } bool deflated = false; ObjectMonitor* free_head_p = NULL; // Local SLL of scavenged monitors ObjectMonitor* free_tail_p = NULL;
*** 2532,2541 **** --- 2562,2572 ---- Atomic::load(&om_list_globals._in_use_count), Atomic::load(&om_list_globals._free_count), Atomic::load(&om_list_globals._wait_count)); // The ServiceThread's async deflation request has been processed. + _last_async_deflation_time_ns = os::javaTimeNanos(); set_is_async_deflation_requested(false); if (Atomic::load(&om_list_globals._wait_count) > 0) { // There are deflated ObjectMonitors waiting for a handshake // (or a safepoint) for safety.
*** 2607,2626 **** } else { OM_PERFDATA_OP(MonExtant, inc(Atomic::load(&target->om_in_use_count))); } do { - if (saved_mid_in_use_p != NULL) { - // We looped around because deflate_monitor_list_using_JT() - // detected a pending safepoint. Honoring the safepoint is good, - // but as long as is_special_deflation_requested() is supported, - // we can't safely restart using saved_mid_in_use_p. That saved - // ObjectMonitor could have been deflated by safepoint based - // deflation and would no longer be on the in-use list where we - // originally found it. - saved_mid_in_use_p = NULL; - } int local_deflated_count; if (is_global) { local_deflated_count = deflate_monitor_list_using_JT(&om_list_globals._in_use_list, &om_list_globals._in_use_count, --- 2638,2647 ----
*** 2699,2712 **** // monitors. Note: if the work is split among more than one // worker thread, then the reported time will likely be more // than a beginning to end measurement of the phase. log_info(safepoint, cleanup)("deflating per-thread idle monitors, %3.7f secs, monitors=%d", counters->per_thread_times, counters->per_thread_scavenged); ! bool needs_special_deflation = is_special_deflation_requested(); ! if (AsyncDeflateIdleMonitors && !needs_special_deflation) { // Nothing to do when idle ObjectMonitors are deflated using ! // a JavaThread unless a special deflation has been requested. return; } if (log_is_enabled(Debug, monitorinflation)) { // exit_globals()'s call to audit_and_print_stats() is done --- 2720,2732 ---- // monitors. Note: if the work is split among more than one // worker thread, then the reported time will likely be more // than a beginning to end measurement of the phase. log_info(safepoint, cleanup)("deflating per-thread idle monitors, %3.7f secs, monitors=%d", counters->per_thread_times, counters->per_thread_scavenged); ! if (AsyncDeflateIdleMonitors) { // Nothing to do when idle ObjectMonitors are deflated using ! // a JavaThread. return; } if (log_is_enabled(Debug, monitorinflation)) { // exit_globals()'s call to audit_and_print_stats() is done
*** 2727,2747 **** OM_PERFDATA_OP(Deflations, inc(counters->n_scavenged)); OM_PERFDATA_OP(MonExtant, set_value(counters->n_in_circulation)); GVars.stw_random = os::random(); GVars.stw_cycle++; - - if (needs_special_deflation) { - set_is_special_deflation_requested(false); // special deflation is done - } } void ObjectSynchronizer::deflate_thread_local_monitors(Thread* thread, DeflateMonitorCounters* counters) { assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); ! if (AsyncDeflateIdleMonitors && !is_special_deflation_requested()) { ! // Nothing to do if a special deflation has NOT been requested. return; } ObjectMonitor* free_head_p = NULL; // Local SLL of scavenged monitors ObjectMonitor* free_tail_p = NULL; --- 2747,2764 ---- OM_PERFDATA_OP(Deflations, inc(counters->n_scavenged)); OM_PERFDATA_OP(MonExtant, set_value(counters->n_in_circulation)); GVars.stw_random = os::random(); GVars.stw_cycle++; } void ObjectSynchronizer::deflate_thread_local_monitors(Thread* thread, DeflateMonitorCounters* counters) { assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); ! if (AsyncDeflateIdleMonitors) { ! // Nothing to do when per-thread idle ObjectMonitors are deflated ! // using a JavaThread. return; } ObjectMonitor* free_head_p = NULL; // Local SLL of scavenged monitors ObjectMonitor* free_tail_p = NULL;
< prev index next >