Merge
This commit is contained in:
commit
042902811c
@ -4799,8 +4799,8 @@ jint os::init_2(void) {
|
||||
FLAG_IS_DEFAULT(UseSHM) &&
|
||||
FLAG_IS_DEFAULT(UseHugeTLBFS)) {
|
||||
UseLargePages = false;
|
||||
} else {
|
||||
warning("UseNUMA is not fully compatible with SHM/HugeTLBFS large pages, disabling adaptive resizing");
|
||||
} else if (UseAdaptiveSizePolicy || UseAdaptiveNUMAChunkSizing) {
|
||||
warning("UseNUMA is not fully compatible with SHM/HugeTLBFS large pages, disabling adaptive resizing (-XX:-UseAdaptiveSizePolicy -XX:-UseAdaptiveNUMAChunkSizing)");
|
||||
UseAdaptiveSizePolicy = false;
|
||||
UseAdaptiveNUMAChunkSizing = false;
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
* 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() {
|
||||
SuspendibleThreadSetJoiner sts;
|
||||
SuspendibleThreadSetJoiner sts_join;
|
||||
G1CollectedHeap* g1h = G1CollectedHeap::heap();
|
||||
G1CollectorPolicy* g1p = g1h->g1_policy();
|
||||
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
|
||||
if (regions_visited == 10) {
|
||||
if (sts.should_yield()) {
|
||||
sts.yield();
|
||||
if (sts_join.should_yield()) {
|
||||
sts_join.yield();
|
||||
// we just abandon the iteration
|
||||
break;
|
||||
}
|
||||
@ -188,7 +188,7 @@ void ConcurrentG1RefineThread::run() {
|
||||
}
|
||||
|
||||
{
|
||||
SuspendibleThreadSetJoiner sts;
|
||||
SuspendibleThreadSetJoiner sts_join;
|
||||
|
||||
do {
|
||||
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) {}
|
||||
|
||||
void work(uint worker_id) {
|
||||
if (_suspendible) {
|
||||
SuspendibleThreadSet::join();
|
||||
}
|
||||
SuspendibleThreadSetJoiner sts_join(_suspendible);
|
||||
G1CollectedHeap::heap()->heap_region_par_iterate(_cl, worker_id, &_hrclaimer, true);
|
||||
if (_suspendible) {
|
||||
SuspendibleThreadSet::leave();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -275,7 +270,6 @@ bool CMMarkStack::allocate(size_t capacity) {
|
||||
_capacity = (jint) capacity;
|
||||
_saved_index = -1;
|
||||
_should_expand = false;
|
||||
NOT_PRODUCT(_max_depth = 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -331,54 +325,6 @@ CMMarkStack::~CMMarkStack() {
|
||||
}
|
||||
}
|
||||
|
||||
void CMMarkStack::par_push(oop ptr) {
|
||||
while (true) {
|
||||
if (isFull()) {
|
||||
_overflow = true;
|
||||
return;
|
||||
}
|
||||
// Otherwise...
|
||||
jint index = _index;
|
||||
jint next_index = index+1;
|
||||
jint res = Atomic::cmpxchg(next_index, &_index, index);
|
||||
if (res == index) {
|
||||
_base[index] = ptr;
|
||||
// Note that we don't maintain this atomically. We could, but it
|
||||
// doesn't seem necessary.
|
||||
NOT_PRODUCT(_max_depth = MAX2(_max_depth, next_index));
|
||||
return;
|
||||
}
|
||||
// Otherwise, we need to try again.
|
||||
}
|
||||
}
|
||||
|
||||
void CMMarkStack::par_adjoin_arr(oop* ptr_arr, int n) {
|
||||
while (true) {
|
||||
if (isFull()) {
|
||||
_overflow = true;
|
||||
return;
|
||||
}
|
||||
// Otherwise...
|
||||
jint index = _index;
|
||||
jint next_index = index + n;
|
||||
if (next_index > _capacity) {
|
||||
_overflow = true;
|
||||
return;
|
||||
}
|
||||
jint res = Atomic::cmpxchg(next_index, &_index, index);
|
||||
if (res == index) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
int ind = index + i;
|
||||
assert(ind < _capacity, "By overflow test above.");
|
||||
_base[ind] = ptr_arr[i];
|
||||
}
|
||||
NOT_PRODUCT(_max_depth = MAX2(_max_depth, next_index));
|
||||
return;
|
||||
}
|
||||
// Otherwise, we need to try again.
|
||||
}
|
||||
}
|
||||
|
||||
void CMMarkStack::par_push_arr(oop* ptr_arr, int n) {
|
||||
MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
|
||||
jint start = _index;
|
||||
@ -394,7 +340,6 @@ void CMMarkStack::par_push_arr(oop* ptr_arr, int n) {
|
||||
assert(ind < _capacity, "By overflow test above.");
|
||||
_base[ind] = ptr_arr[i];
|
||||
}
|
||||
NOT_PRODUCT(_max_depth = MAX2(_max_depth, next_index));
|
||||
}
|
||||
|
||||
bool CMMarkStack::par_pop_arr(oop* ptr_arr, int max, int* n) {
|
||||
@ -1006,19 +951,17 @@ void ConcurrentMark::checkpointRootsInitialPost() {
|
||||
*/
|
||||
|
||||
void ConcurrentMark::enter_first_sync_barrier(uint worker_id) {
|
||||
bool barrier_aborted;
|
||||
|
||||
if (verbose_low()) {
|
||||
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
|
||||
// more work
|
||||
|
||||
@ -1065,19 +1008,17 @@ void ConcurrentMark::enter_first_sync_barrier(uint worker_id) {
|
||||
}
|
||||
|
||||
void ConcurrentMark::enter_second_sync_barrier(uint worker_id) {
|
||||
bool barrier_aborted;
|
||||
|
||||
if (verbose_low()) {
|
||||
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
|
||||
|
||||
if (verbose_low()) {
|
||||
@ -1128,40 +1069,41 @@ public:
|
||||
|
||||
double start_vtime = os::elapsedVTime();
|
||||
|
||||
SuspendibleThreadSet::join();
|
||||
{
|
||||
SuspendibleThreadSetJoiner sts_join;
|
||||
|
||||
assert(worker_id < _cm->active_tasks(), "invariant");
|
||||
CMTask* the_task = _cm->task(worker_id);
|
||||
the_task->record_start_time();
|
||||
if (!_cm->has_aborted()) {
|
||||
do {
|
||||
double start_vtime_sec = os::elapsedVTime();
|
||||
double mark_step_duration_ms = G1ConcMarkStepDurationMillis;
|
||||
assert(worker_id < _cm->active_tasks(), "invariant");
|
||||
CMTask* the_task = _cm->task(worker_id);
|
||||
the_task->record_start_time();
|
||||
if (!_cm->has_aborted()) {
|
||||
do {
|
||||
double start_vtime_sec = os::elapsedVTime();
|
||||
double mark_step_duration_ms = G1ConcMarkStepDurationMillis;
|
||||
|
||||
the_task->do_marking_step(mark_step_duration_ms,
|
||||
true /* do_termination */,
|
||||
false /* is_serial*/);
|
||||
the_task->do_marking_step(mark_step_duration_ms,
|
||||
true /* do_termination */,
|
||||
false /* is_serial*/);
|
||||
|
||||
double end_vtime_sec = os::elapsedVTime();
|
||||
double elapsed_vtime_sec = end_vtime_sec - start_vtime_sec;
|
||||
_cm->clear_has_overflown();
|
||||
double end_vtime_sec = os::elapsedVTime();
|
||||
double elapsed_vtime_sec = end_vtime_sec - start_vtime_sec;
|
||||
_cm->clear_has_overflown();
|
||||
|
||||
_cm->do_yield_check(worker_id);
|
||||
_cm->do_yield_check(worker_id);
|
||||
|
||||
jlong sleep_time_ms;
|
||||
if (!_cm->has_aborted() && the_task->has_aborted()) {
|
||||
sleep_time_ms =
|
||||
(jlong) (elapsed_vtime_sec * _cm->sleep_factor() * 1000.0);
|
||||
SuspendibleThreadSet::leave();
|
||||
os::sleep(Thread::current(), sleep_time_ms, false);
|
||||
SuspendibleThreadSet::join();
|
||||
}
|
||||
} while (!_cm->has_aborted() && the_task->has_aborted());
|
||||
jlong sleep_time_ms;
|
||||
if (!_cm->has_aborted() && the_task->has_aborted()) {
|
||||
sleep_time_ms =
|
||||
(jlong) (elapsed_vtime_sec * _cm->sleep_factor() * 1000.0);
|
||||
{
|
||||
SuspendibleThreadSetLeaver sts_leave;
|
||||
os::sleep(Thread::current(), sleep_time_ms, false);
|
||||
}
|
||||
}
|
||||
} 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();
|
||||
_cm->update_accum_task_vtime(worker_id, end_vtime - start_vtime);
|
||||
|
@ -180,25 +180,12 @@ class CMMarkStack VALUE_OBJ_CLASS_SPEC {
|
||||
jint _index; // one more than last occupied index
|
||||
jint _capacity; // max #elements
|
||||
jint _saved_index; // value of _index saved at start of GC
|
||||
NOT_PRODUCT(jint _max_depth;) // max depth plumbed during run
|
||||
|
||||
bool _overflow;
|
||||
bool _should_expand;
|
||||
DEBUG_ONLY(bool _drain_in_progress;)
|
||||
DEBUG_ONLY(bool _drain_in_progress_yields;)
|
||||
|
||||
public:
|
||||
CMMarkStack(ConcurrentMark* cm);
|
||||
~CMMarkStack();
|
||||
|
||||
#ifndef PRODUCT
|
||||
jint max_depth() const {
|
||||
return _max_depth;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool allocate(size_t capacity);
|
||||
|
||||
oop pop() {
|
||||
if (!isEmpty()) {
|
||||
return _base[--_index] ;
|
||||
@ -206,27 +193,11 @@ class CMMarkStack VALUE_OBJ_CLASS_SPEC {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// If overflow happens, don't do the push, and record the overflow.
|
||||
// *Requires* that "ptr" is already marked.
|
||||
void push(oop ptr) {
|
||||
if (isFull()) {
|
||||
// Record overflow.
|
||||
_overflow = true;
|
||||
return;
|
||||
} else {
|
||||
_base[_index++] = ptr;
|
||||
NOT_PRODUCT(_max_depth = MAX2(_max_depth, _index));
|
||||
}
|
||||
}
|
||||
// Non-block impl. Note: concurrency is allowed only with other
|
||||
// "par_push" operations, not with "pop" or "drain". We would need
|
||||
// parallel versions of them if such concurrency was desired.
|
||||
void par_push(oop ptr);
|
||||
public:
|
||||
CMMarkStack(ConcurrentMark* cm);
|
||||
~CMMarkStack();
|
||||
|
||||
// Pushes the first "n" elements of "ptr_arr" on the stack.
|
||||
// Non-block impl. Note: concurrency is allowed only with other
|
||||
// "par_adjoin_arr" or "push" operations, not with "pop" or "drain".
|
||||
void par_adjoin_arr(oop* ptr_arr, int n);
|
||||
bool allocate(size_t capacity);
|
||||
|
||||
// Pushes the first "n" elements of "ptr_arr" on the stack.
|
||||
// Locking impl: concurrency is allowed only with
|
||||
@ -254,7 +225,6 @@ class CMMarkStack VALUE_OBJ_CLASS_SPEC {
|
||||
bool drain(OopClosureClass* cl, CMBitMap* bm, bool yield_after = false);
|
||||
|
||||
bool isEmpty() { return _index == 0; }
|
||||
bool isFull() { return _index == _capacity; }
|
||||
int maxElems() { return _capacity; }
|
||||
|
||||
bool overflow() { return _overflow; }
|
||||
@ -378,7 +348,6 @@ class ConcurrentMark: public CHeapObj<mtGC> {
|
||||
friend class ConcurrentMarkThread;
|
||||
friend class CMTask;
|
||||
friend class CMBitMapClosure;
|
||||
friend class CMGlobalObjectClosure;
|
||||
friend class CMRemarkTask;
|
||||
friend class CMConcurrentMarkingTask;
|
||||
friend class G1ParNoteEndTask;
|
||||
@ -473,8 +442,8 @@ protected:
|
||||
// All of these times are in ms
|
||||
NumberSeq _init_times;
|
||||
NumberSeq _remark_times;
|
||||
NumberSeq _remark_mark_times;
|
||||
NumberSeq _remark_weak_ref_times;
|
||||
NumberSeq _remark_mark_times;
|
||||
NumberSeq _remark_weak_ref_times;
|
||||
NumberSeq _cleanup_times;
|
||||
double _total_counting_time;
|
||||
double _total_rs_scrub_time;
|
||||
@ -623,19 +592,9 @@ protected:
|
||||
|
||||
public:
|
||||
// Manipulation of the global mark stack.
|
||||
// Notice that the first mark_stack_push is CAS-based, whereas the
|
||||
// two below are Mutex-based. This is OK since the first one is only
|
||||
// called during evacuation pauses and doesn't compete with the
|
||||
// other two (which are called by the marking tasks during
|
||||
// concurrent marking or remark).
|
||||
bool mark_stack_push(oop p) {
|
||||
_markStack.par_push(p);
|
||||
if (_markStack.overflow()) {
|
||||
set_has_overflown();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// The push and pop operations are used by tasks for transfers
|
||||
// between task-local queues and the global mark stack, and use
|
||||
// locking for concurrency safety.
|
||||
bool mark_stack_push(oop* arr, int n) {
|
||||
_markStack.par_push_arr(arr, n);
|
||||
if (_markStack.overflow()) {
|
||||
|
@ -192,7 +192,7 @@ void ConcurrentMarkThread::run() {
|
||||
} else {
|
||||
// We don't want to update the marking status if a GC pause
|
||||
// is already underway.
|
||||
SuspendibleThreadSetJoiner sts;
|
||||
SuspendibleThreadSetJoiner sts_join;
|
||||
g1h->set_marking_complete();
|
||||
}
|
||||
|
||||
@ -262,7 +262,7 @@ void ConcurrentMarkThread::run() {
|
||||
// not needed any more as the concurrent mark state has been
|
||||
// already reset).
|
||||
{
|
||||
SuspendibleThreadSetJoiner sts;
|
||||
SuspendibleThreadSetJoiner sts_join;
|
||||
if (!cm()->has_aborted()) {
|
||||
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
|
||||
// called System.gc() with +ExplicitGCInvokesConcurrent).
|
||||
{
|
||||
SuspendibleThreadSetJoiner sts;
|
||||
SuspendibleThreadSetJoiner sts_join;
|
||||
g1h->increment_old_marking_cycles_completed(true /* concurrent */);
|
||||
g1h->register_concurrent_cycle_end();
|
||||
}
|
||||
|
@ -1877,13 +1877,18 @@ jint G1CollectedHeap::initialize() {
|
||||
// Carve out the G1 part of the heap.
|
||||
|
||||
ReservedSpace g1_rs = heap_rs.first_part(max_byte_size);
|
||||
size_t page_size = UseLargePages ? os::large_page_size() : os::vm_page_size();
|
||||
G1RegionToSpaceMapper* heap_storage =
|
||||
G1RegionToSpaceMapper::create_mapper(g1_rs,
|
||||
g1_rs.size(),
|
||||
UseLargePages ? os::large_page_size() : os::vm_page_size(),
|
||||
page_size,
|
||||
HeapRegion::GrainBytes,
|
||||
1,
|
||||
mtJavaHeap);
|
||||
os::trace_page_sizes("G1 Heap", collector_policy()->min_heap_byte_size(),
|
||||
max_byte_size, page_size,
|
||||
heap_rs.base(),
|
||||
heap_rs.size());
|
||||
heap_storage->set_mapping_changed_listener(&_listener);
|
||||
|
||||
// Create storage for the BOT, card table, card counts table (hot card cache) and the bitmaps.
|
||||
|
@ -74,7 +74,7 @@ void G1StringDedupThread::run() {
|
||||
|
||||
{
|
||||
// Include thread in safepoints
|
||||
SuspendibleThreadSetJoiner sts;
|
||||
SuspendibleThreadSetJoiner sts_join;
|
||||
|
||||
stat.mark_exec();
|
||||
|
||||
@ -88,9 +88,9 @@ void G1StringDedupThread::run() {
|
||||
G1StringDedupTable::deduplicate(java_string, stat);
|
||||
|
||||
// Safepoint this thread if needed
|
||||
if (sts.should_yield()) {
|
||||
if (sts_join.should_yield()) {
|
||||
stat.mark_block();
|
||||
sts.yield();
|
||||
sts_join.yield();
|
||||
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.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -33,16 +33,20 @@ bool SuspendibleThreadSet::_suspend_all = false;
|
||||
double SuspendibleThreadSet::_suspend_all_start = 0.0;
|
||||
|
||||
void SuspendibleThreadSet::join() {
|
||||
assert(!Thread::current()->is_suspendible_thread(), "Thread already joined");
|
||||
MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
|
||||
while (_suspend_all) {
|
||||
ml.wait(Mutex::_no_safepoint_check_flag);
|
||||
}
|
||||
_nthreads++;
|
||||
DEBUG_ONLY(Thread::current()->set_suspendible_thread();)
|
||||
}
|
||||
|
||||
void SuspendibleThreadSet::leave() {
|
||||
assert(Thread::current()->is_suspendible_thread(), "Thread not joined");
|
||||
MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
|
||||
assert(_nthreads > 0, "Invalid");
|
||||
DEBUG_ONLY(Thread::current()->clear_suspendible_thread();)
|
||||
_nthreads--;
|
||||
if (_suspend_all) {
|
||||
ml.notify_all();
|
||||
@ -50,6 +54,7 @@ void SuspendibleThreadSet::leave() {
|
||||
}
|
||||
|
||||
void SuspendibleThreadSet::yield() {
|
||||
assert(Thread::current()->is_suspendible_thread(), "Must have joined");
|
||||
if (_suspend_all) {
|
||||
MonitorLockerEx ml(STS_lock, Mutex::_no_safepoint_check_flag);
|
||||
if (_suspend_all) {
|
||||
|
@ -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.
|
||||
*
|
||||
* 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
|
||||
// threads to continue.
|
||||
class SuspendibleThreadSet : public AllStatic {
|
||||
friend class SuspendibleThreadSetJoiner;
|
||||
friend class SuspendibleThreadSetLeaver;
|
||||
|
||||
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();
|
||||
|
||||
public:
|
||||
// Returns true if an suspension is in progress.
|
||||
static bool should_yield() { return _suspend_all; }
|
||||
|
||||
@ -63,22 +66,52 @@ public:
|
||||
};
|
||||
|
||||
class SuspendibleThreadSetJoiner : public StackObj {
|
||||
private:
|
||||
bool _active;
|
||||
|
||||
public:
|
||||
SuspendibleThreadSetJoiner() {
|
||||
SuspendibleThreadSet::join();
|
||||
SuspendibleThreadSetJoiner(bool active = true) : _active(active) {
|
||||
if (_active) {
|
||||
SuspendibleThreadSet::join();
|
||||
}
|
||||
}
|
||||
|
||||
~SuspendibleThreadSetJoiner() {
|
||||
SuspendibleThreadSet::leave();
|
||||
if (_active) {
|
||||
SuspendibleThreadSet::leave();
|
||||
}
|
||||
}
|
||||
|
||||
bool should_yield() {
|
||||
return SuspendibleThreadSet::should_yield();
|
||||
if (_active) {
|
||||
return SuspendibleThreadSet::should_yield();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void yield() {
|
||||
assert(_active, "Thread has not joined the suspendible thread set");
|
||||
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
|
||||
|
@ -53,7 +53,7 @@ void PeriodicTask::real_time_tick(int delay_time) {
|
||||
if (ProfilerCheckIntervals) {
|
||||
_ticks++;
|
||||
_timer.stop();
|
||||
int ms = (int)(_timer.seconds() * 1000.0);
|
||||
int ms = (int)_timer.milliseconds();
|
||||
_timer.reset();
|
||||
_timer.start();
|
||||
if (ms >= PeriodicTask::max_interval) ms = PeriodicTask::max_interval - 1;
|
||||
|
@ -190,6 +190,7 @@ Thread::Thread() {
|
||||
set_stack_size(0);
|
||||
set_self_raw_id(0);
|
||||
set_lgrp_id(-1);
|
||||
DEBUG_ONLY(clear_suspendible_thread();)
|
||||
|
||||
// allocated data structures
|
||||
set_osthread(NULL);
|
||||
|
@ -204,11 +204,25 @@ class Thread: public ThreadShadow {
|
||||
private:
|
||||
int _num_nested_signal;
|
||||
|
||||
DEBUG_ONLY(bool _suspendible_thread;)
|
||||
|
||||
public:
|
||||
void enter_signal_handler() { _num_nested_signal++; }
|
||||
void leave_signal_handler() { _num_nested_signal--; }
|
||||
bool is_inside_signal_handler() const { return _num_nested_signal > 0; }
|
||||
|
||||
#ifdef ASSERT
|
||||
void set_suspendible_thread() {
|
||||
_suspendible_thread = true;
|
||||
}
|
||||
|
||||
void clear_suspendible_thread() {
|
||||
_suspendible_thread = false;
|
||||
}
|
||||
|
||||
bool is_suspendible_thread() { return _suspendible_thread; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
// Active_handles points to a block of handles
|
||||
JNIHandleBlock* _active_handles;
|
||||
|
@ -28,9 +28,12 @@
|
||||
#include "utilities/ostream.hpp"
|
||||
|
||||
double TimeHelper::counter_to_seconds(jlong counter) {
|
||||
double count = (double) counter;
|
||||
double freq = (double) os::elapsed_frequency();
|
||||
return counter/freq;
|
||||
return counter / freq;
|
||||
}
|
||||
|
||||
double TimeHelper::counter_to_millis(jlong counter) {
|
||||
return counter_to_seconds(counter) * 1000.0;
|
||||
}
|
||||
|
||||
void elapsedTimer::add(elapsedTimer t) {
|
||||
@ -56,8 +59,7 @@ double elapsedTimer::seconds() const {
|
||||
}
|
||||
|
||||
jlong elapsedTimer::milliseconds() const {
|
||||
jlong ticks_per_ms = os::elapsed_frequency() / 1000;
|
||||
return _counter / ticks_per_ms;
|
||||
return TimeHelper::counter_to_millis(_counter);
|
||||
}
|
||||
|
||||
jlong elapsedTimer::active_ticks() const {
|
||||
@ -86,11 +88,8 @@ double TimeStamp::seconds() const {
|
||||
|
||||
jlong TimeStamp::milliseconds() const {
|
||||
assert(is_updated(), "must not be clear");
|
||||
|
||||
jlong new_count = os::elapsed_counter();
|
||||
jlong count = new_count - _counter;
|
||||
jlong ticks_per_ms = os::elapsed_frequency() / 1000;
|
||||
return count / ticks_per_ms;
|
||||
return TimeHelper::counter_to_millis(new_count - _counter);
|
||||
}
|
||||
|
||||
jlong TimeStamp::ticks_since_update() const {
|
||||
|
@ -123,6 +123,7 @@ class TraceCPUTime: public StackObj {
|
||||
class TimeHelper {
|
||||
public:
|
||||
static double counter_to_seconds(jlong counter);
|
||||
static double counter_to_millis(jlong counter);
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_RUNTIME_TIMER_HPP
|
||||
|
Loading…
x
Reference in New Issue
Block a user