/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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/g1/concurrentG1Refine.hpp"
#include "gc_implementation/g1/concurrentG1RefineThread.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1CollectorPolicy.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/mutexLocker.hpp"
int worker_id_offset, int worker_id) :
_active(false),
_vtime_accum(0.0)
{
// Each thread has its own monitor. The i-th thread is responsible for signalling
// to thread i+1 if the number of buffers in the queue exceeds a threashold for this
// thread. Monitors are also used to wake up the threads during termination.
// The 0th worker in notified by mutator threads and has a special monitor.
// The last worker is used for young gen rset size sampling.
if (worker_id > 0) {
} else {
}
initialize();
}
// Current thread activation threshold
cg1r()->yellow_zone());
// A thread deactivates once the number of buffer reached a deactivation threshold
_deactivation_threshold = MAX2<int>(_threshold - cg1r()->thread_threshold_step(), cg1r()->green_zone());
} else {
set_active(true);
}
}
if (g1p->adaptive_young_list_length()) {
int regions_visited = 0;
// we try to yield every time we visit 10 regions
if (regions_visited == 10) {
if (_sts.should_yield()) {
// we just abandon the iteration
break;
}
regions_visited = 0;
}
}
}
}
while(!_should_terminate) {
if (os::supports_vtime()) {
} else {
_vtime_accum = 0.0;
}
if (_should_terminate) {
break;
}
}
}
while (!_should_terminate && !is_active()) {
}
}
}
if (_worker_id > 0) {
if (G1TraceConcRefinement) {
}
set_active(true);
} else {
dcqs.set_process_completed(true);
}
}
if (_worker_id > 0) {
if (G1TraceConcRefinement) {
}
set_active(false);
} else {
dcqs.set_process_completed(false);
}
}
terminate();
return;
}
while (!_should_terminate) {
// Wait for work
if (_should_terminate) {
break;
}
do {
// If the number of the buffers falls down into the yellow zone,
// that means that the transition period after the evacuation pause has ended.
}
// If the number of the buffer has fallen below our threshold
// we should deactivate. The predecessor will reactivate this
// thread should the number of the buffers cross the threshold again.
deactivate();
break;
}
// Check if we need to activate the next thread.
}
} 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();
}
if (os::supports_vtime()) {
} else {
_vtime_accum = 0.0;
}
}
terminate();
}
if (G1TraceConcRefinement) {
}
if (G1TraceConcRefinement) {
}
}
// it is ok to take late safepoints here, if needed
{
_should_terminate = true;
}
{
}
{
while (!_has_terminated) {
Terminator_lock->wait();
}
}
if (G1TraceConcRefinement) {
}
}
}
}