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