8079579: Add SuspendibleThreadSetLeaver and make SuspendibleThreadSet::joint()/leave() private
Reviewed-by: brutisso, david
This commit is contained in:
parent
5b29324b68
commit
95da544d68
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -77,7 +77,7 @@ void ConcurrentG1RefineThread::initialize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConcurrentG1RefineThread::sample_young_list_rs_lengths() {
|
void ConcurrentG1RefineThread::sample_young_list_rs_lengths() {
|
||||||
SuspendibleThreadSetJoiner sts;
|
SuspendibleThreadSetJoiner sts_join;
|
||||||
G1CollectedHeap* g1h = G1CollectedHeap::heap();
|
G1CollectedHeap* g1h = G1CollectedHeap::heap();
|
||||||
G1CollectorPolicy* g1p = g1h->g1_policy();
|
G1CollectorPolicy* g1p = g1h->g1_policy();
|
||||||
if (g1p->adaptive_young_list_length()) {
|
if (g1p->adaptive_young_list_length()) {
|
||||||
@ -89,8 +89,8 @@ void ConcurrentG1RefineThread::sample_young_list_rs_lengths() {
|
|||||||
|
|
||||||
// we try to yield every time we visit 10 regions
|
// we try to yield every time we visit 10 regions
|
||||||
if (regions_visited == 10) {
|
if (regions_visited == 10) {
|
||||||
if (sts.should_yield()) {
|
if (sts_join.should_yield()) {
|
||||||
sts.yield();
|
sts_join.yield();
|
||||||
// we just abandon the iteration
|
// we just abandon the iteration
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -188,7 +188,7 @@ void ConcurrentG1RefineThread::run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
SuspendibleThreadSetJoiner sts;
|
SuspendibleThreadSetJoiner sts_join;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
int curr_buffer_num = (int)dcqs.completed_buffers_num();
|
int curr_buffer_num = (int)dcqs.completed_buffers_num();
|
||||||
|
@ -193,13 +193,8 @@ public:
|
|||||||
_cl(cl), _suspendible(suspendible), AbstractGangTask("Parallel Clear Bitmap Task"), _hrclaimer(n_workers) {}
|
_cl(cl), _suspendible(suspendible), AbstractGangTask("Parallel Clear Bitmap Task"), _hrclaimer(n_workers) {}
|
||||||
|
|
||||||
void work(uint worker_id) {
|
void work(uint worker_id) {
|
||||||
if (_suspendible) {
|
SuspendibleThreadSetJoiner sts_join(_suspendible);
|
||||||
SuspendibleThreadSet::join();
|
|
||||||
}
|
|
||||||
G1CollectedHeap::heap()->heap_region_par_iterate(_cl, worker_id, &_hrclaimer, true);
|
G1CollectedHeap::heap()->heap_region_par_iterate(_cl, worker_id, &_hrclaimer, true);
|
||||||
if (_suspendible) {
|
|
||||||
SuspendibleThreadSet::leave();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -956,19 +951,17 @@ void ConcurrentMark::checkpointRootsInitialPost() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void ConcurrentMark::enter_first_sync_barrier(uint worker_id) {
|
void ConcurrentMark::enter_first_sync_barrier(uint worker_id) {
|
||||||
|
bool barrier_aborted;
|
||||||
|
|
||||||
if (verbose_low()) {
|
if (verbose_low()) {
|
||||||
gclog_or_tty->print_cr("[%u] entering first barrier", worker_id);
|
gclog_or_tty->print_cr("[%u] entering first barrier", worker_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (concurrent()) {
|
{
|
||||||
SuspendibleThreadSet::leave();
|
SuspendibleThreadSetLeaver sts_leave(concurrent());
|
||||||
|
barrier_aborted = !_first_overflow_barrier_sync.enter();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool barrier_aborted = !_first_overflow_barrier_sync.enter();
|
|
||||||
|
|
||||||
if (concurrent()) {
|
|
||||||
SuspendibleThreadSet::join();
|
|
||||||
}
|
|
||||||
// at this point everyone should have synced up and not be doing any
|
// at this point everyone should have synced up and not be doing any
|
||||||
// more work
|
// more work
|
||||||
|
|
||||||
@ -1015,19 +1008,17 @@ void ConcurrentMark::enter_first_sync_barrier(uint worker_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConcurrentMark::enter_second_sync_barrier(uint worker_id) {
|
void ConcurrentMark::enter_second_sync_barrier(uint worker_id) {
|
||||||
|
bool barrier_aborted;
|
||||||
|
|
||||||
if (verbose_low()) {
|
if (verbose_low()) {
|
||||||
gclog_or_tty->print_cr("[%u] entering second barrier", worker_id);
|
gclog_or_tty->print_cr("[%u] entering second barrier", worker_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (concurrent()) {
|
{
|
||||||
SuspendibleThreadSet::leave();
|
SuspendibleThreadSetLeaver sts_leave(concurrent());
|
||||||
|
barrier_aborted = !_second_overflow_barrier_sync.enter();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool barrier_aborted = !_second_overflow_barrier_sync.enter();
|
|
||||||
|
|
||||||
if (concurrent()) {
|
|
||||||
SuspendibleThreadSet::join();
|
|
||||||
}
|
|
||||||
// at this point everything should be re-initialized and ready to go
|
// at this point everything should be re-initialized and ready to go
|
||||||
|
|
||||||
if (verbose_low()) {
|
if (verbose_low()) {
|
||||||
@ -1078,40 +1069,41 @@ public:
|
|||||||
|
|
||||||
double start_vtime = os::elapsedVTime();
|
double start_vtime = os::elapsedVTime();
|
||||||
|
|
||||||
SuspendibleThreadSet::join();
|
{
|
||||||
|
SuspendibleThreadSetJoiner sts_join;
|
||||||
|
|
||||||
assert(worker_id < _cm->active_tasks(), "invariant");
|
assert(worker_id < _cm->active_tasks(), "invariant");
|
||||||
CMTask* the_task = _cm->task(worker_id);
|
CMTask* the_task = _cm->task(worker_id);
|
||||||
the_task->record_start_time();
|
the_task->record_start_time();
|
||||||
if (!_cm->has_aborted()) {
|
if (!_cm->has_aborted()) {
|
||||||
do {
|
do {
|
||||||
double start_vtime_sec = os::elapsedVTime();
|
double start_vtime_sec = os::elapsedVTime();
|
||||||
double mark_step_duration_ms = G1ConcMarkStepDurationMillis;
|
double mark_step_duration_ms = G1ConcMarkStepDurationMillis;
|
||||||
|
|
||||||
the_task->do_marking_step(mark_step_duration_ms,
|
the_task->do_marking_step(mark_step_duration_ms,
|
||||||
true /* do_termination */,
|
true /* do_termination */,
|
||||||
false /* is_serial*/);
|
false /* is_serial*/);
|
||||||
|
|
||||||
double end_vtime_sec = os::elapsedVTime();
|
double end_vtime_sec = os::elapsedVTime();
|
||||||
double elapsed_vtime_sec = end_vtime_sec - start_vtime_sec;
|
double elapsed_vtime_sec = end_vtime_sec - start_vtime_sec;
|
||||||
_cm->clear_has_overflown();
|
_cm->clear_has_overflown();
|
||||||
|
|
||||||
_cm->do_yield_check(worker_id);
|
_cm->do_yield_check(worker_id);
|
||||||
|
|
||||||
jlong sleep_time_ms;
|
jlong sleep_time_ms;
|
||||||
if (!_cm->has_aborted() && the_task->has_aborted()) {
|
if (!_cm->has_aborted() && the_task->has_aborted()) {
|
||||||
sleep_time_ms =
|
sleep_time_ms =
|
||||||
(jlong) (elapsed_vtime_sec * _cm->sleep_factor() * 1000.0);
|
(jlong) (elapsed_vtime_sec * _cm->sleep_factor() * 1000.0);
|
||||||
SuspendibleThreadSet::leave();
|
{
|
||||||
os::sleep(Thread::current(), sleep_time_ms, false);
|
SuspendibleThreadSetLeaver sts_leave;
|
||||||
SuspendibleThreadSet::join();
|
os::sleep(Thread::current(), sleep_time_ms, false);
|
||||||
}
|
}
|
||||||
} while (!_cm->has_aborted() && the_task->has_aborted());
|
}
|
||||||
|
} while (!_cm->has_aborted() && the_task->has_aborted());
|
||||||
|
}
|
||||||
|
the_task->record_end_time();
|
||||||
|
guarantee(!the_task->has_aborted() || _cm->has_aborted(), "invariant");
|
||||||
}
|
}
|
||||||
the_task->record_end_time();
|
|
||||||
guarantee(!the_task->has_aborted() || _cm->has_aborted(), "invariant");
|
|
||||||
|
|
||||||
SuspendibleThreadSet::leave();
|
|
||||||
|
|
||||||
double end_vtime = os::elapsedVTime();
|
double end_vtime = os::elapsedVTime();
|
||||||
_cm->update_accum_task_vtime(worker_id, end_vtime - start_vtime);
|
_cm->update_accum_task_vtime(worker_id, end_vtime - start_vtime);
|
||||||
|
@ -192,7 +192,7 @@ void ConcurrentMarkThread::run() {
|
|||||||
} else {
|
} else {
|
||||||
// We don't want to update the marking status if a GC pause
|
// We don't want to update the marking status if a GC pause
|
||||||
// is already underway.
|
// is already underway.
|
||||||
SuspendibleThreadSetJoiner sts;
|
SuspendibleThreadSetJoiner sts_join;
|
||||||
g1h->set_marking_complete();
|
g1h->set_marking_complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,7 +262,7 @@ void ConcurrentMarkThread::run() {
|
|||||||
// not needed any more as the concurrent mark state has been
|
// not needed any more as the concurrent mark state has been
|
||||||
// already reset).
|
// already reset).
|
||||||
{
|
{
|
||||||
SuspendibleThreadSetJoiner sts;
|
SuspendibleThreadSetJoiner sts_join;
|
||||||
if (!cm()->has_aborted()) {
|
if (!cm()->has_aborted()) {
|
||||||
g1_policy->record_concurrent_mark_cleanup_completed();
|
g1_policy->record_concurrent_mark_cleanup_completed();
|
||||||
}
|
}
|
||||||
@ -291,7 +291,7 @@ void ConcurrentMarkThread::run() {
|
|||||||
// Java thread is waiting for a full GC to happen (e.g., it
|
// Java thread is waiting for a full GC to happen (e.g., it
|
||||||
// called System.gc() with +ExplicitGCInvokesConcurrent).
|
// called System.gc() with +ExplicitGCInvokesConcurrent).
|
||||||
{
|
{
|
||||||
SuspendibleThreadSetJoiner sts;
|
SuspendibleThreadSetJoiner sts_join;
|
||||||
g1h->increment_old_marking_cycles_completed(true /* concurrent */);
|
g1h->increment_old_marking_cycles_completed(true /* concurrent */);
|
||||||
g1h->register_concurrent_cycle_end();
|
g1h->register_concurrent_cycle_end();
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ void G1StringDedupThread::run() {
|
|||||||
|
|
||||||
{
|
{
|
||||||
// Include thread in safepoints
|
// Include thread in safepoints
|
||||||
SuspendibleThreadSetJoiner sts;
|
SuspendibleThreadSetJoiner sts_join;
|
||||||
|
|
||||||
stat.mark_exec();
|
stat.mark_exec();
|
||||||
|
|
||||||
@ -88,9 +88,9 @@ void G1StringDedupThread::run() {
|
|||||||
G1StringDedupTable::deduplicate(java_string, stat);
|
G1StringDedupTable::deduplicate(java_string, stat);
|
||||||
|
|
||||||
// Safepoint this thread if needed
|
// Safepoint this thread if needed
|
||||||
if (sts.should_yield()) {
|
if (sts_join.should_yield()) {
|
||||||
stat.mark_block();
|
stat.mark_block();
|
||||||
sts.yield();
|
sts_join.yield();
|
||||||
stat.mark_unblock();
|
stat.mark_unblock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -36,19 +36,22 @@
|
|||||||
// suspending thread later calls desynchronize(), allowing the suspended
|
// suspending thread later calls desynchronize(), allowing the suspended
|
||||||
// threads to continue.
|
// threads to continue.
|
||||||
class SuspendibleThreadSet : public AllStatic {
|
class SuspendibleThreadSet : public AllStatic {
|
||||||
|
friend class SuspendibleThreadSetJoiner;
|
||||||
|
friend class SuspendibleThreadSetLeaver;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static uint _nthreads;
|
static uint _nthreads;
|
||||||
static uint _nthreads_stopped;
|
static uint _nthreads_stopped;
|
||||||
static bool _suspend_all;
|
static bool _suspend_all;
|
||||||
static double _suspend_all_start;
|
static double _suspend_all_start;
|
||||||
|
|
||||||
public:
|
|
||||||
// Add the current thread to the set. May block if a suspension is in progress.
|
// Add the current thread to the set. May block if a suspension is in progress.
|
||||||
static void join();
|
static void join();
|
||||||
|
|
||||||
// Removes the current thread from the set.
|
// Removes the current thread from the set.
|
||||||
static void leave();
|
static void leave();
|
||||||
|
|
||||||
|
public:
|
||||||
// Returns true if an suspension is in progress.
|
// Returns true if an suspension is in progress.
|
||||||
static bool should_yield() { return _suspend_all; }
|
static bool should_yield() { return _suspend_all; }
|
||||||
|
|
||||||
@ -63,22 +66,52 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
class SuspendibleThreadSetJoiner : public StackObj {
|
class SuspendibleThreadSetJoiner : public StackObj {
|
||||||
|
private:
|
||||||
|
bool _active;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SuspendibleThreadSetJoiner() {
|
SuspendibleThreadSetJoiner(bool active = true) : _active(active) {
|
||||||
SuspendibleThreadSet::join();
|
if (_active) {
|
||||||
|
SuspendibleThreadSet::join();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~SuspendibleThreadSetJoiner() {
|
~SuspendibleThreadSetJoiner() {
|
||||||
SuspendibleThreadSet::leave();
|
if (_active) {
|
||||||
|
SuspendibleThreadSet::leave();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool should_yield() {
|
bool should_yield() {
|
||||||
return SuspendibleThreadSet::should_yield();
|
if (_active) {
|
||||||
|
return SuspendibleThreadSet::should_yield();
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void yield() {
|
void yield() {
|
||||||
|
assert(_active, "Thread has not joined the suspendible thread set");
|
||||||
SuspendibleThreadSet::yield();
|
SuspendibleThreadSet::yield();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SuspendibleThreadSetLeaver : public StackObj {
|
||||||
|
private:
|
||||||
|
bool _active;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SuspendibleThreadSetLeaver(bool active = true) : _active(active) {
|
||||||
|
if (_active) {
|
||||||
|
SuspendibleThreadSet::leave();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~SuspendibleThreadSetLeaver() {
|
||||||
|
if (_active) {
|
||||||
|
SuspendibleThreadSet::join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_SUSPENDIBLETHREADSET_HPP
|
#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_SUSPENDIBLETHREADSET_HPP
|
||||||
|
Loading…
x
Reference in New Issue
Block a user