8039147: Cleanup SuspendibleThreadSet
Reviewed-by: brutisso, tschatzl, mgerdin
This commit is contained in:
parent
a3425b64f0
commit
f1edf66ef8
@ -71,6 +71,7 @@ void ConcurrentG1RefineThread::initialize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConcurrentG1RefineThread::sample_young_list_rs_lengths() {
|
void ConcurrentG1RefineThread::sample_young_list_rs_lengths() {
|
||||||
|
SuspendibleThreadSetJoiner sts;
|
||||||
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()) {
|
||||||
@ -82,8 +83,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.should_yield()) {
|
||||||
_sts.yield("G1 refine");
|
sts.yield();
|
||||||
// we just abandon the iteration
|
// we just abandon the iteration
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -99,9 +100,7 @@ void ConcurrentG1RefineThread::run_young_rs_sampling() {
|
|||||||
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
|
||||||
_vtime_start = os::elapsedVTime();
|
_vtime_start = os::elapsedVTime();
|
||||||
while(!_should_terminate) {
|
while(!_should_terminate) {
|
||||||
_sts.join();
|
|
||||||
sample_young_list_rs_lengths();
|
sample_young_list_rs_lengths();
|
||||||
_sts.leave();
|
|
||||||
|
|
||||||
if (os::supports_vtime()) {
|
if (os::supports_vtime()) {
|
||||||
_vtime_accum = (os::elapsedVTime() - _vtime_start);
|
_vtime_accum = (os::elapsedVTime() - _vtime_start);
|
||||||
@ -182,37 +181,37 @@ void ConcurrentG1RefineThread::run() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_sts.join();
|
{
|
||||||
|
SuspendibleThreadSetJoiner sts;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
int curr_buffer_num = (int)dcqs.completed_buffers_num();
|
int curr_buffer_num = (int)dcqs.completed_buffers_num();
|
||||||
// If the number of the buffers falls down into the yellow zone,
|
// If the number of the buffers falls down into the yellow zone,
|
||||||
// that means that the transition period after the evacuation pause has ended.
|
// that means that the transition period after the evacuation pause has ended.
|
||||||
if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= cg1r()->yellow_zone()) {
|
if (dcqs.completed_queue_padding() > 0 && curr_buffer_num <= cg1r()->yellow_zone()) {
|
||||||
dcqs.set_completed_queue_padding(0);
|
dcqs.set_completed_queue_padding(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_worker_id > 0 && curr_buffer_num <= _deactivation_threshold) {
|
if (_worker_id > 0 && curr_buffer_num <= _deactivation_threshold) {
|
||||||
// If the number of the buffer has fallen below our threshold
|
// If the number of the buffer has fallen below our threshold
|
||||||
// we should deactivate. The predecessor will reactivate this
|
// we should deactivate. The predecessor will reactivate this
|
||||||
// thread should the number of the buffers cross the threshold again.
|
// thread should the number of the buffers cross the threshold again.
|
||||||
|
deactivate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we need to activate the next thread.
|
||||||
|
if (_next != NULL && !_next->is_active() && curr_buffer_num > _next->_threshold) {
|
||||||
|
_next->activate();
|
||||||
|
}
|
||||||
|
} while (dcqs.apply_closure_to_completed_buffer(_worker_id + _worker_id_offset, cg1r()->green_zone()));
|
||||||
|
|
||||||
|
// We can exit the loop above while being active if there was a yield request.
|
||||||
|
if (is_active()) {
|
||||||
deactivate();
|
deactivate();
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we need to activate the next thread.
|
|
||||||
if (_next != NULL && !_next->is_active() && curr_buffer_num > _next->_threshold) {
|
|
||||||
_next->activate();
|
|
||||||
}
|
|
||||||
} while (dcqs.apply_closure_to_completed_buffer(_worker_id + _worker_id_offset, cg1r()->green_zone()));
|
|
||||||
|
|
||||||
// We can exit the loop above while being active if there was a yield request.
|
|
||||||
if (is_active()) {
|
|
||||||
deactivate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_sts.leave();
|
|
||||||
|
|
||||||
if (os::supports_vtime()) {
|
if (os::supports_vtime()) {
|
||||||
_vtime_accum = (os::elapsedVTime() - _vtime_start);
|
_vtime_accum = (os::elapsedVTime() - _vtime_start);
|
||||||
} else {
|
} else {
|
||||||
@ -223,17 +222,6 @@ void ConcurrentG1RefineThread::run() {
|
|||||||
terminate();
|
terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ConcurrentG1RefineThread::yield() {
|
|
||||||
if (G1TraceConcRefinement) {
|
|
||||||
gclog_or_tty->print_cr("G1-Refine-yield");
|
|
||||||
}
|
|
||||||
_sts.yield("G1 refine");
|
|
||||||
if (G1TraceConcRefinement) {
|
|
||||||
gclog_or_tty->print_cr("G1-Refine-yield-end");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConcurrentG1RefineThread::stop() {
|
void ConcurrentG1RefineThread::stop() {
|
||||||
// it is ok to take late safepoints here, if needed
|
// it is ok to take late safepoints here, if needed
|
||||||
{
|
{
|
||||||
|
@ -64,9 +64,6 @@ class ConcurrentG1RefineThread: public ConcurrentGCThread {
|
|||||||
void activate();
|
void activate();
|
||||||
void deactivate();
|
void deactivate();
|
||||||
|
|
||||||
// For use by G1CollectedHeap, which is a friend.
|
|
||||||
static SuspendibleThreadSet* sts() { return &_sts; }
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void run();
|
virtual void run();
|
||||||
// Constructor
|
// Constructor
|
||||||
@ -84,8 +81,6 @@ public:
|
|||||||
|
|
||||||
ConcurrentG1Refine* cg1r() { return _cg1r; }
|
ConcurrentG1Refine* cg1r() { return _cg1r; }
|
||||||
|
|
||||||
// Yield for GC
|
|
||||||
void yield();
|
|
||||||
// shutdown
|
// shutdown
|
||||||
void stop();
|
void stop();
|
||||||
};
|
};
|
||||||
|
@ -976,11 +976,11 @@ void ConcurrentMark::enter_first_sync_barrier(uint worker_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (concurrent()) {
|
if (concurrent()) {
|
||||||
ConcurrentGCThread::stsLeave();
|
SuspendibleThreadSet::leave();
|
||||||
}
|
}
|
||||||
_first_overflow_barrier_sync.enter();
|
_first_overflow_barrier_sync.enter();
|
||||||
if (concurrent()) {
|
if (concurrent()) {
|
||||||
ConcurrentGCThread::stsJoin();
|
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
|
||||||
@ -1024,11 +1024,11 @@ void ConcurrentMark::enter_second_sync_barrier(uint worker_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (concurrent()) {
|
if (concurrent()) {
|
||||||
ConcurrentGCThread::stsLeave();
|
SuspendibleThreadSet::leave();
|
||||||
}
|
}
|
||||||
_second_overflow_barrier_sync.enter();
|
_second_overflow_barrier_sync.enter();
|
||||||
if (concurrent()) {
|
if (concurrent()) {
|
||||||
ConcurrentGCThread::stsJoin();
|
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
|
||||||
|
|
||||||
@ -1076,7 +1076,7 @@ public:
|
|||||||
|
|
||||||
double start_vtime = os::elapsedVTime();
|
double start_vtime = os::elapsedVTime();
|
||||||
|
|
||||||
ConcurrentGCThread::stsJoin();
|
SuspendibleThreadSet::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);
|
||||||
@ -1103,9 +1103,9 @@ public:
|
|||||||
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);
|
||||||
ConcurrentGCThread::stsLeave();
|
SuspendibleThreadSet::leave();
|
||||||
os::sleep(Thread::current(), sleep_time_ms, false);
|
os::sleep(Thread::current(), sleep_time_ms, false);
|
||||||
ConcurrentGCThread::stsJoin();
|
SuspendibleThreadSet::join();
|
||||||
}
|
}
|
||||||
double end_time2_sec = os::elapsedTime();
|
double end_time2_sec = os::elapsedTime();
|
||||||
double elapsed_time2_sec = end_time2_sec - start_time_sec;
|
double elapsed_time2_sec = end_time2_sec - start_time_sec;
|
||||||
@ -1123,7 +1123,7 @@ public:
|
|||||||
the_task->record_end_time();
|
the_task->record_end_time();
|
||||||
guarantee(!the_task->has_aborted() || _cm->has_aborted(), "invariant");
|
guarantee(!the_task->has_aborted() || _cm->has_aborted(), "invariant");
|
||||||
|
|
||||||
ConcurrentGCThread::stsLeave();
|
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);
|
||||||
@ -3302,21 +3302,17 @@ void ConcurrentMark::print_on_error(outputStream* st) const {
|
|||||||
|
|
||||||
// We take a break if someone is trying to stop the world.
|
// We take a break if someone is trying to stop the world.
|
||||||
bool ConcurrentMark::do_yield_check(uint worker_id) {
|
bool ConcurrentMark::do_yield_check(uint worker_id) {
|
||||||
if (should_yield()) {
|
if (SuspendibleThreadSet::should_yield()) {
|
||||||
if (worker_id == 0) {
|
if (worker_id == 0) {
|
||||||
_g1h->g1_policy()->record_concurrent_pause();
|
_g1h->g1_policy()->record_concurrent_pause();
|
||||||
}
|
}
|
||||||
cmThread()->yield();
|
SuspendibleThreadSet::yield();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConcurrentMark::should_yield() {
|
|
||||||
return cmThread()->should_yield();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConcurrentMark::containing_card_is_marked(void* p) {
|
bool ConcurrentMark::containing_card_is_marked(void* p) {
|
||||||
size_t offset = pointer_delta(p, _g1h->reserved_region().start(), 1);
|
size_t offset = pointer_delta(p, _g1h->reserved_region().start(), 1);
|
||||||
return _card_bm.at(offset >> CardTableModRefBS::card_shift);
|
return _card_bm.at(offset >> CardTableModRefBS::card_shift);
|
||||||
@ -3605,7 +3601,7 @@ void CMTask::regular_clock_call() {
|
|||||||
#endif // _MARKING_STATS_
|
#endif // _MARKING_STATS_
|
||||||
|
|
||||||
// (4) We check whether we should yield. If we have to, then we abort.
|
// (4) We check whether we should yield. If we have to, then we abort.
|
||||||
if (_cm->should_yield()) {
|
if (SuspendibleThreadSet::should_yield()) {
|
||||||
// We should yield. To do this we abort the task. The caller is
|
// We should yield. To do this we abort the task. The caller is
|
||||||
// responsible for yielding.
|
// responsible for yielding.
|
||||||
set_has_aborted();
|
set_has_aborted();
|
||||||
|
@ -814,7 +814,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline bool do_yield_check(uint worker_i = 0);
|
inline bool do_yield_check(uint worker_i = 0);
|
||||||
inline bool should_yield();
|
|
||||||
|
|
||||||
// Called to abort the marking cycle after a Full GC takes place.
|
// Called to abort the marking cycle after a Full GC takes place.
|
||||||
void abort();
|
void abort();
|
||||||
|
@ -194,9 +194,8 @@ 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.
|
||||||
_sts.join();
|
SuspendibleThreadSetJoiner sts;
|
||||||
g1h->set_marking_complete();
|
g1h->set_marking_complete();
|
||||||
_sts.leave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if cleanup set the free_regions_coming flag. If it
|
// Check if cleanup set the free_regions_coming flag. If it
|
||||||
@ -266,11 +265,12 @@ void ConcurrentMarkThread::run() {
|
|||||||
// record_concurrent_mark_cleanup_completed() (and, in fact, it's
|
// record_concurrent_mark_cleanup_completed() (and, in fact, it's
|
||||||
// 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).
|
||||||
_sts.join();
|
{
|
||||||
if (!cm()->has_aborted()) {
|
SuspendibleThreadSetJoiner sts;
|
||||||
g1_policy->record_concurrent_mark_cleanup_completed();
|
if (!cm()->has_aborted()) {
|
||||||
|
g1_policy->record_concurrent_mark_cleanup_completed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_sts.leave();
|
|
||||||
|
|
||||||
if (cm()->has_aborted()) {
|
if (cm()->has_aborted()) {
|
||||||
if (G1Log::fine()) {
|
if (G1Log::fine()) {
|
||||||
@ -282,30 +282,27 @@ void ConcurrentMarkThread::run() {
|
|||||||
|
|
||||||
// We now want to allow clearing of the marking bitmap to be
|
// We now want to allow clearing of the marking bitmap to be
|
||||||
// suspended by a collection pause.
|
// suspended by a collection pause.
|
||||||
_sts.join();
|
{
|
||||||
_cm->clearNextBitmap();
|
SuspendibleThreadSetJoiner sts;
|
||||||
_sts.leave();
|
_cm->clearNextBitmap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the number of full collections that have been
|
// Update the number of full collections that have been
|
||||||
// completed. This will also notify the FullGCCount_lock in case a
|
// completed. This will also notify the FullGCCount_lock in case a
|
||||||
// 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).
|
||||||
_sts.join();
|
{
|
||||||
g1h->increment_old_marking_cycles_completed(true /* concurrent */);
|
SuspendibleThreadSetJoiner sts;
|
||||||
g1h->register_concurrent_cycle_end();
|
g1h->increment_old_marking_cycles_completed(true /* concurrent */);
|
||||||
_sts.leave();
|
g1h->register_concurrent_cycle_end();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
assert(_should_terminate, "just checking");
|
assert(_should_terminate, "just checking");
|
||||||
|
|
||||||
terminate();
|
terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ConcurrentMarkThread::yield() {
|
|
||||||
_sts.yield("Concurrent Mark");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConcurrentMarkThread::stop() {
|
void ConcurrentMarkThread::stop() {
|
||||||
{
|
{
|
||||||
MutexLockerEx ml(Terminator_lock);
|
MutexLockerEx ml(Terminator_lock);
|
||||||
|
@ -89,9 +89,6 @@ class ConcurrentMarkThread: public ConcurrentGCThread {
|
|||||||
// that started() is set and set in_progress().
|
// that started() is set and set in_progress().
|
||||||
bool during_cycle() { return started() || in_progress(); }
|
bool during_cycle() { return started() || in_progress(); }
|
||||||
|
|
||||||
// Yield for GC
|
|
||||||
void yield();
|
|
||||||
|
|
||||||
// shutdown
|
// shutdown
|
||||||
void stop();
|
void stop();
|
||||||
};
|
};
|
||||||
|
@ -92,15 +92,13 @@ size_t G1CollectedHeap::_humongous_object_threshold_in_words = 0;
|
|||||||
// Local to this file.
|
// Local to this file.
|
||||||
|
|
||||||
class RefineCardTableEntryClosure: public CardTableEntryClosure {
|
class RefineCardTableEntryClosure: public CardTableEntryClosure {
|
||||||
SuspendibleThreadSet* _sts;
|
|
||||||
G1RemSet* _g1rs;
|
G1RemSet* _g1rs;
|
||||||
ConcurrentG1Refine* _cg1r;
|
ConcurrentG1Refine* _cg1r;
|
||||||
bool _concurrent;
|
bool _concurrent;
|
||||||
public:
|
public:
|
||||||
RefineCardTableEntryClosure(SuspendibleThreadSet* sts,
|
RefineCardTableEntryClosure(G1RemSet* g1rs,
|
||||||
G1RemSet* g1rs,
|
|
||||||
ConcurrentG1Refine* cg1r) :
|
ConcurrentG1Refine* cg1r) :
|
||||||
_sts(sts), _g1rs(g1rs), _cg1r(cg1r), _concurrent(true)
|
_g1rs(g1rs), _cg1r(cg1r), _concurrent(true)
|
||||||
{}
|
{}
|
||||||
bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
|
bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
|
||||||
bool oops_into_cset = _g1rs->refine_card(card_ptr, worker_i, false);
|
bool oops_into_cset = _g1rs->refine_card(card_ptr, worker_i, false);
|
||||||
@ -109,7 +107,7 @@ public:
|
|||||||
// that point into the collection set.
|
// that point into the collection set.
|
||||||
assert(!oops_into_cset, "should be");
|
assert(!oops_into_cset, "should be");
|
||||||
|
|
||||||
if (_concurrent && _sts->should_yield()) {
|
if (_concurrent && SuspendibleThreadSet::should_yield()) {
|
||||||
// Caller will actually yield.
|
// Caller will actually yield.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2117,8 +2115,7 @@ jint G1CollectedHeap::initialize() {
|
|||||||
g1_policy()->init();
|
g1_policy()->init();
|
||||||
|
|
||||||
_refine_cte_cl =
|
_refine_cte_cl =
|
||||||
new RefineCardTableEntryClosure(ConcurrentG1RefineThread::sts(),
|
new RefineCardTableEntryClosure(g1_rem_set(),
|
||||||
g1_rem_set(),
|
|
||||||
concurrent_g1_refine());
|
concurrent_g1_refine());
|
||||||
JavaThread::dirty_card_queue_set().set_closure(_refine_cte_cl);
|
JavaThread::dirty_card_queue_set().set_closure(_refine_cte_cl);
|
||||||
|
|
||||||
@ -4317,7 +4314,7 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
|
|||||||
// this point does not assume that we are the only GC thread
|
// this point does not assume that we are the only GC thread
|
||||||
// running. Note: of course, the actual marking work will
|
// running. Note: of course, the actual marking work will
|
||||||
// not start until the safepoint itself is released in
|
// not start until the safepoint itself is released in
|
||||||
// ConcurrentGCThread::safepoint_desynchronize().
|
// SuspendibleThreadSet::desynchronize().
|
||||||
doConcurrentMark();
|
doConcurrentMark();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,38 +77,37 @@ void G1StringDedupThread::run() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include this thread in safepoints
|
{
|
||||||
stsJoin();
|
// Include thread in safepoints
|
||||||
|
SuspendibleThreadSetJoiner sts;
|
||||||
|
|
||||||
stat.mark_exec();
|
stat.mark_exec();
|
||||||
|
|
||||||
// Process the queue
|
// Process the queue
|
||||||
for (;;) {
|
for (;;) {
|
||||||
oop java_string = G1StringDedupQueue::pop();
|
oop java_string = G1StringDedupQueue::pop();
|
||||||
if (java_string == NULL) {
|
if (java_string == NULL) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
G1StringDedupTable::deduplicate(java_string, stat);
|
||||||
|
|
||||||
|
// Safepoint this thread if needed
|
||||||
|
if (sts.should_yield()) {
|
||||||
|
stat.mark_block();
|
||||||
|
sts.yield();
|
||||||
|
stat.mark_unblock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
G1StringDedupTable::deduplicate(java_string, stat);
|
G1StringDedupTable::trim_entry_cache();
|
||||||
|
|
||||||
// Safepoint this thread if needed
|
stat.mark_done();
|
||||||
if (stsShouldYield()) {
|
|
||||||
stat.mark_block();
|
// Print statistics
|
||||||
stsYield(NULL);
|
total_stat.add(stat);
|
||||||
stat.mark_unblock();
|
print(gclog_or_tty, stat, total_stat);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
G1StringDedupTable::trim_entry_cache();
|
|
||||||
|
|
||||||
stat.mark_done();
|
|
||||||
|
|
||||||
// Print statistics
|
|
||||||
total_stat.add(stat);
|
|
||||||
print(gclog_or_tty, stat, total_stat);
|
|
||||||
|
|
||||||
// Exclude this thread from safepoints
|
|
||||||
stsLeave();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
terminate();
|
terminate();
|
||||||
|
@ -37,21 +37,10 @@
|
|||||||
|
|
||||||
int ConcurrentGCThread::_CGC_flag = CGC_nil;
|
int ConcurrentGCThread::_CGC_flag = CGC_nil;
|
||||||
|
|
||||||
SuspendibleThreadSet ConcurrentGCThread::_sts;
|
|
||||||
|
|
||||||
ConcurrentGCThread::ConcurrentGCThread() :
|
ConcurrentGCThread::ConcurrentGCThread() :
|
||||||
_should_terminate(false), _has_terminated(false) {
|
_should_terminate(false), _has_terminated(false) {
|
||||||
_sts.initialize();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void ConcurrentGCThread::safepoint_synchronize() {
|
|
||||||
_sts.suspend_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConcurrentGCThread::safepoint_desynchronize() {
|
|
||||||
_sts.resume_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConcurrentGCThread::create_and_start() {
|
void ConcurrentGCThread::create_and_start() {
|
||||||
if (os::create_thread(this, os::cgc_thread)) {
|
if (os::create_thread(this, os::cgc_thread)) {
|
||||||
// XXX: need to set this to low priority
|
// XXX: need to set this to low priority
|
||||||
@ -92,78 +81,6 @@ void ConcurrentGCThread::terminate() {
|
|||||||
ThreadLocalStorage::set_thread(NULL);
|
ThreadLocalStorage::set_thread(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SuspendibleThreadSet::initialize_work() {
|
|
||||||
MutexLocker x(STS_init_lock);
|
|
||||||
if (!_initialized) {
|
|
||||||
_m = new Monitor(Mutex::leaf,
|
|
||||||
"SuspendibleThreadSetLock", true);
|
|
||||||
_async = 0;
|
|
||||||
_async_stop = false;
|
|
||||||
_async_stopped = 0;
|
|
||||||
_initialized = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SuspendibleThreadSet::join() {
|
|
||||||
initialize();
|
|
||||||
MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
|
|
||||||
while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag);
|
|
||||||
_async++;
|
|
||||||
assert(_async > 0, "Huh.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void SuspendibleThreadSet::leave() {
|
|
||||||
assert(_initialized, "Must be initialized.");
|
|
||||||
MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
|
|
||||||
_async--;
|
|
||||||
assert(_async >= 0, "Huh.");
|
|
||||||
if (_async_stop) _m->notify_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SuspendibleThreadSet::yield(const char* id) {
|
|
||||||
assert(_initialized, "Must be initialized.");
|
|
||||||
if (_async_stop) {
|
|
||||||
MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
|
|
||||||
if (_async_stop) {
|
|
||||||
_async_stopped++;
|
|
||||||
assert(_async_stopped > 0, "Huh.");
|
|
||||||
if (_async_stopped == _async) {
|
|
||||||
if (ConcGCYieldTimeout > 0) {
|
|
||||||
double now = os::elapsedTime();
|
|
||||||
guarantee((now - _suspend_all_start) * 1000.0 <
|
|
||||||
(double)ConcGCYieldTimeout,
|
|
||||||
"Long delay; whodunit?");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_m->notify_all();
|
|
||||||
while (_async_stop) _m->wait(Mutex::_no_safepoint_check_flag);
|
|
||||||
_async_stopped--;
|
|
||||||
assert(_async >= 0, "Huh");
|
|
||||||
_m->notify_all();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SuspendibleThreadSet::suspend_all() {
|
|
||||||
initialize(); // If necessary.
|
|
||||||
if (ConcGCYieldTimeout > 0) {
|
|
||||||
_suspend_all_start = os::elapsedTime();
|
|
||||||
}
|
|
||||||
MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
|
|
||||||
assert(!_async_stop, "Only one at a time.");
|
|
||||||
_async_stop = true;
|
|
||||||
while (_async_stopped < _async) _m->wait(Mutex::_no_safepoint_check_flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SuspendibleThreadSet::resume_all() {
|
|
||||||
assert(_initialized, "Must be initialized.");
|
|
||||||
MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag);
|
|
||||||
assert(_async_stopped == _async, "Huh.");
|
|
||||||
_async_stop = false;
|
|
||||||
_m->notify_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _sltLoop(JavaThread* thread, TRAPS) {
|
static void _sltLoop(JavaThread* thread, TRAPS) {
|
||||||
SurrogateLockerThread* slt = (SurrogateLockerThread*)thread;
|
SurrogateLockerThread* slt = (SurrogateLockerThread*)thread;
|
||||||
slt->loop();
|
slt->loop();
|
||||||
@ -283,30 +200,3 @@ void SurrogateLockerThread::loop() {
|
|||||||
}
|
}
|
||||||
assert(!_monitor.owned_by_self(), "Should unlock before exit.");
|
assert(!_monitor.owned_by_self(), "Should unlock before exit.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ===== STS Access From Outside CGCT =====
|
|
||||||
|
|
||||||
void ConcurrentGCThread::stsYield(const char* id) {
|
|
||||||
assert( Thread::current()->is_ConcurrentGC_thread(),
|
|
||||||
"only a conc GC thread can call this" );
|
|
||||||
_sts.yield(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ConcurrentGCThread::stsShouldYield() {
|
|
||||||
assert( Thread::current()->is_ConcurrentGC_thread(),
|
|
||||||
"only a conc GC thread can call this" );
|
|
||||||
return _sts.should_yield();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConcurrentGCThread::stsJoin() {
|
|
||||||
assert( Thread::current()->is_ConcurrentGC_thread(),
|
|
||||||
"only a conc GC thread can call this" );
|
|
||||||
_sts.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConcurrentGCThread::stsLeave() {
|
|
||||||
assert( Thread::current()->is_ConcurrentGC_thread(),
|
|
||||||
"only a conc GC thread can call this" );
|
|
||||||
_sts.leave();
|
|
||||||
}
|
|
||||||
|
@ -26,55 +26,8 @@
|
|||||||
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_CONCURRENTGCTHREAD_HPP
|
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_CONCURRENTGCTHREAD_HPP
|
||||||
|
|
||||||
#include "utilities/macros.hpp"
|
#include "utilities/macros.hpp"
|
||||||
#if INCLUDE_ALL_GCS
|
#include "gc_implementation/shared/suspendibleThreadSet.hpp"
|
||||||
#include "runtime/thread.hpp"
|
#include "runtime/thread.hpp"
|
||||||
#endif // INCLUDE_ALL_GCS
|
|
||||||
|
|
||||||
class VoidClosure;
|
|
||||||
|
|
||||||
// A SuspendibleThreadSet is (obviously) a set of threads that can be
|
|
||||||
// suspended. A thread can join and later leave the set, and periodically
|
|
||||||
// yield. If some thread (not in the set) requests, via suspend_all, that
|
|
||||||
// the threads be suspended, then the requesting thread is blocked until
|
|
||||||
// all the threads in the set have yielded or left the set. (Threads may
|
|
||||||
// not enter the set when an attempted suspension is in progress.) The
|
|
||||||
// suspending thread later calls resume_all, allowing the suspended threads
|
|
||||||
// to continue.
|
|
||||||
|
|
||||||
class SuspendibleThreadSet {
|
|
||||||
Monitor* _m;
|
|
||||||
int _async;
|
|
||||||
bool _async_stop;
|
|
||||||
int _async_stopped;
|
|
||||||
bool _initialized;
|
|
||||||
double _suspend_all_start;
|
|
||||||
|
|
||||||
void initialize_work();
|
|
||||||
|
|
||||||
public:
|
|
||||||
SuspendibleThreadSet() : _initialized(false) {}
|
|
||||||
|
|
||||||
// Add the current thread to the set. May block if a suspension
|
|
||||||
// is in progress.
|
|
||||||
void join();
|
|
||||||
// Removes the current thread from the set.
|
|
||||||
void leave();
|
|
||||||
// Returns "true" iff an suspension is in progress.
|
|
||||||
bool should_yield() { return _async_stop; }
|
|
||||||
// Suspends the current thread if a suspension is in progress (for
|
|
||||||
// the duration of the suspension.)
|
|
||||||
void yield(const char* id);
|
|
||||||
// Return when all threads in the set are suspended.
|
|
||||||
void suspend_all();
|
|
||||||
// Allow suspended threads to resume.
|
|
||||||
void resume_all();
|
|
||||||
// Redundant initializations okay.
|
|
||||||
void initialize() {
|
|
||||||
// Double-check dirty read idiom.
|
|
||||||
if (!_initialized) initialize_work();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class ConcurrentGCThread: public NamedThread {
|
class ConcurrentGCThread: public NamedThread {
|
||||||
friend class VMStructs;
|
friend class VMStructs;
|
||||||
@ -96,9 +49,6 @@ protected:
|
|||||||
static int set_CGC_flag(int b) { return _CGC_flag |= b; }
|
static int set_CGC_flag(int b) { return _CGC_flag |= b; }
|
||||||
static int reset_CGC_flag(int b) { return _CGC_flag &= ~b; }
|
static int reset_CGC_flag(int b) { return _CGC_flag &= ~b; }
|
||||||
|
|
||||||
// All instances share this one set.
|
|
||||||
static SuspendibleThreadSet _sts;
|
|
||||||
|
|
||||||
// Create and start the thread (setting it's priority high.)
|
// Create and start the thread (setting it's priority high.)
|
||||||
void create_and_start();
|
void create_and_start();
|
||||||
|
|
||||||
@ -121,25 +71,6 @@ public:
|
|||||||
|
|
||||||
// Tester
|
// Tester
|
||||||
bool is_ConcurrentGC_thread() const { return true; }
|
bool is_ConcurrentGC_thread() const { return true; }
|
||||||
|
|
||||||
static void safepoint_synchronize();
|
|
||||||
static void safepoint_desynchronize();
|
|
||||||
|
|
||||||
// All overridings should probably do _sts::yield, but we allow
|
|
||||||
// overriding for distinguished debugging messages. Default is to do
|
|
||||||
// nothing.
|
|
||||||
virtual void yield() {}
|
|
||||||
|
|
||||||
bool should_yield() { return _sts.should_yield(); }
|
|
||||||
|
|
||||||
// they are prefixed by sts since there are already yield() and
|
|
||||||
// should_yield() (non-static) methods in this class and it was an
|
|
||||||
// easy way to differentiate them.
|
|
||||||
static void stsYield(const char* id);
|
|
||||||
static bool stsShouldYield();
|
|
||||||
static void stsJoin();
|
|
||||||
static void stsLeave();
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// The SurrogateLockerThread is used by concurrent GC threads for
|
// The SurrogateLockerThread is used by concurrent GC threads for
|
||||||
|
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "precompiled.hpp"
|
||||||
|
#include "gc_implementation/shared/suspendibleThreadSet.hpp"
|
||||||
|
#include "runtime/mutexLocker.hpp"
|
||||||
|
#include "runtime/thread.inline.hpp"
|
||||||
|
|
||||||
|
uint SuspendibleThreadSet::_nthreads = 0;
|
||||||
|
uint SuspendibleThreadSet::_nthreads_stopped = 0;
|
||||||
|
bool SuspendibleThreadSet::_suspend_all = false;
|
||||||
|
double SuspendibleThreadSet::_suspend_all_start = 0.0;
|
||||||
|
|
||||||
|
void SuspendibleThreadSet::join() {
|
||||||
|
MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
|
||||||
|
while (_suspend_all) {
|
||||||
|
ml.wait(Mutex::_no_safepoint_check_flag);
|
||||||
|
}
|
||||||
|
_nthreads++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SuspendibleThreadSet::leave() {
|
||||||
|
MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
|
||||||
|
assert(_nthreads > 0, "Invalid");
|
||||||
|
_nthreads--;
|
||||||
|
if (_suspend_all) {
|
||||||
|
ml.notify_all();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SuspendibleThreadSet::yield() {
|
||||||
|
if (_suspend_all) {
|
||||||
|
MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
|
||||||
|
if (_suspend_all) {
|
||||||
|
_nthreads_stopped++;
|
||||||
|
if (_nthreads_stopped == _nthreads) {
|
||||||
|
if (ConcGCYieldTimeout > 0) {
|
||||||
|
double now = os::elapsedTime();
|
||||||
|
guarantee((now - _suspend_all_start) * 1000.0 < (double)ConcGCYieldTimeout, "Long delay");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ml.notify_all();
|
||||||
|
while (_suspend_all) {
|
||||||
|
ml.wait(Mutex::_no_safepoint_check_flag);
|
||||||
|
}
|
||||||
|
assert(_nthreads_stopped > 0, "Invalid");
|
||||||
|
_nthreads_stopped--;
|
||||||
|
ml.notify_all();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SuspendibleThreadSet::synchronize() {
|
||||||
|
assert(Thread::current()->is_VM_thread(), "Must be the VM thread");
|
||||||
|
if (ConcGCYieldTimeout > 0) {
|
||||||
|
_suspend_all_start = os::elapsedTime();
|
||||||
|
}
|
||||||
|
MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
|
||||||
|
assert(!_suspend_all, "Only one at a time");
|
||||||
|
_suspend_all = true;
|
||||||
|
while (_nthreads_stopped < _nthreads) {
|
||||||
|
ml.wait(Mutex::_no_safepoint_check_flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SuspendibleThreadSet::desynchronize() {
|
||||||
|
assert(Thread::current()->is_VM_thread(), "Must be the VM thread");
|
||||||
|
MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
|
||||||
|
assert(_nthreads_stopped == _nthreads, "Invalid");
|
||||||
|
_suspend_all = false;
|
||||||
|
ml.notify_all();
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_SUSPENDIBLETHREADSET_HPP
|
||||||
|
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_SUSPENDIBLETHREADSET_HPP
|
||||||
|
|
||||||
|
#include "memory/allocation.hpp"
|
||||||
|
|
||||||
|
// A SuspendibleThreadSet is a set of threads that can be suspended.
|
||||||
|
// A thread can join and later leave the set, and periodically yield.
|
||||||
|
// If some thread (not in the set) requests, via synchronize(), that
|
||||||
|
// the threads be suspended, then the requesting thread is blocked
|
||||||
|
// until all the threads in the set have yielded or left the set. Threads
|
||||||
|
// may not enter the set when an attempted suspension is in progress. The
|
||||||
|
// suspending thread later calls desynchronize(), allowing the suspended
|
||||||
|
// threads to continue.
|
||||||
|
class SuspendibleThreadSet : public AllStatic {
|
||||||
|
private:
|
||||||
|
static uint _nthreads;
|
||||||
|
static uint _nthreads_stopped;
|
||||||
|
static bool _suspend_all;
|
||||||
|
static double _suspend_all_start;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Add the current thread to the set. May block if a suspension is in progress.
|
||||||
|
static void join();
|
||||||
|
|
||||||
|
// Removes the current thread from the set.
|
||||||
|
static void leave();
|
||||||
|
|
||||||
|
// Returns true if an suspension is in progress.
|
||||||
|
static bool should_yield() { return _suspend_all; }
|
||||||
|
|
||||||
|
// Suspends the current thread if a suspension is in progress.
|
||||||
|
static void yield();
|
||||||
|
|
||||||
|
// Returns when all threads in the set are suspended.
|
||||||
|
static void synchronize();
|
||||||
|
|
||||||
|
// Resumes all suspended threads in the set.
|
||||||
|
static void desynchronize();
|
||||||
|
};
|
||||||
|
|
||||||
|
class SuspendibleThreadSetJoiner : public StackObj {
|
||||||
|
public:
|
||||||
|
SuspendibleThreadSetJoiner() {
|
||||||
|
SuspendibleThreadSet::join();
|
||||||
|
}
|
||||||
|
|
||||||
|
~SuspendibleThreadSetJoiner() {
|
||||||
|
SuspendibleThreadSet::leave();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool should_yield() {
|
||||||
|
return SuspendibleThreadSet::should_yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
void yield() {
|
||||||
|
SuspendibleThreadSet::yield();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_SUSPENDIBLETHREADSET_HPP
|
@ -69,7 +69,7 @@ Monitor* Safepoint_lock = NULL;
|
|||||||
Monitor* SerializePage_lock = NULL;
|
Monitor* SerializePage_lock = NULL;
|
||||||
Monitor* Threads_lock = NULL;
|
Monitor* Threads_lock = NULL;
|
||||||
Monitor* CGC_lock = NULL;
|
Monitor* CGC_lock = NULL;
|
||||||
Mutex* STS_init_lock = NULL;
|
Monitor* STS_lock = NULL;
|
||||||
Monitor* SLT_lock = NULL;
|
Monitor* SLT_lock = NULL;
|
||||||
Monitor* iCMS_lock = NULL;
|
Monitor* iCMS_lock = NULL;
|
||||||
Monitor* FullGCCount_lock = NULL;
|
Monitor* FullGCCount_lock = NULL;
|
||||||
@ -173,7 +173,7 @@ void mutex_init() {
|
|||||||
def(tty_lock , Mutex , event, true ); // allow to lock in VM
|
def(tty_lock , Mutex , event, true ); // allow to lock in VM
|
||||||
|
|
||||||
def(CGC_lock , Monitor, special, true ); // coordinate between fore- and background GC
|
def(CGC_lock , Monitor, special, true ); // coordinate between fore- and background GC
|
||||||
def(STS_init_lock , Mutex, leaf, true );
|
def(STS_lock , Monitor, leaf, true );
|
||||||
if (UseConcMarkSweepGC) {
|
if (UseConcMarkSweepGC) {
|
||||||
def(iCMS_lock , Monitor, special, true ); // CMS incremental mode start/stop notification
|
def(iCMS_lock , Monitor, special, true ); // CMS incremental mode start/stop notification
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ extern Monitor* Threads_lock; // a lock on the Threads table
|
|||||||
// (also used by Safepoints too to block threads creation/destruction)
|
// (also used by Safepoints too to block threads creation/destruction)
|
||||||
extern Monitor* CGC_lock; // used for coordination between
|
extern Monitor* CGC_lock; // used for coordination between
|
||||||
// fore- & background GC threads.
|
// fore- & background GC threads.
|
||||||
extern Mutex* STS_init_lock; // coordinate initialization of SuspendibleThreadSets.
|
extern Monitor* STS_lock; // used for joining/leaving SuspendibleThreadSet.
|
||||||
extern Monitor* SLT_lock; // used in CMS GC for acquiring PLL
|
extern Monitor* SLT_lock; // used in CMS GC for acquiring PLL
|
||||||
extern Monitor* iCMS_lock; // CMS incremental mode start/stop notification
|
extern Monitor* iCMS_lock; // CMS incremental mode start/stop notification
|
||||||
extern Monitor* FullGCCount_lock; // in support of "concurrent" full gc
|
extern Monitor* FullGCCount_lock; // in support of "concurrent" full gc
|
||||||
|
@ -75,7 +75,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#if INCLUDE_ALL_GCS
|
#if INCLUDE_ALL_GCS
|
||||||
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
|
#include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp"
|
||||||
#include "gc_implementation/shared/concurrentGCThread.hpp"
|
#include "gc_implementation/shared/suspendibleThreadSet.hpp"
|
||||||
#endif // INCLUDE_ALL_GCS
|
#endif // INCLUDE_ALL_GCS
|
||||||
#ifdef COMPILER1
|
#ifdef COMPILER1
|
||||||
#include "c1/c1_globals.hpp"
|
#include "c1/c1_globals.hpp"
|
||||||
@ -110,7 +110,7 @@ void SafepointSynchronize::begin() {
|
|||||||
// more-general mechanism below. DLD (01/05).
|
// more-general mechanism below. DLD (01/05).
|
||||||
ConcurrentMarkSweepThread::synchronize(false);
|
ConcurrentMarkSweepThread::synchronize(false);
|
||||||
} else if (UseG1GC) {
|
} else if (UseG1GC) {
|
||||||
ConcurrentGCThread::safepoint_synchronize();
|
SuspendibleThreadSet::synchronize();
|
||||||
}
|
}
|
||||||
#endif // INCLUDE_ALL_GCS
|
#endif // INCLUDE_ALL_GCS
|
||||||
|
|
||||||
@ -486,7 +486,7 @@ void SafepointSynchronize::end() {
|
|||||||
if (UseConcMarkSweepGC) {
|
if (UseConcMarkSweepGC) {
|
||||||
ConcurrentMarkSweepThread::desynchronize(false);
|
ConcurrentMarkSweepThread::desynchronize(false);
|
||||||
} else if (UseG1GC) {
|
} else if (UseG1GC) {
|
||||||
ConcurrentGCThread::safepoint_desynchronize();
|
SuspendibleThreadSet::desynchronize();
|
||||||
}
|
}
|
||||||
#endif // INCLUDE_ALL_GCS
|
#endif // INCLUDE_ALL_GCS
|
||||||
// record this time so VMThread can keep track how much time has elapsed
|
// record this time so VMThread can keep track how much time has elapsed
|
||||||
|
Loading…
x
Reference in New Issue
Block a user