Path: blob/master/src/hotspot/share/gc/g1/g1BatchedGangTask.cpp
40957 views
/*1* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"2526#include "gc/g1/g1BatchedGangTask.hpp"27#include "gc/g1/g1CollectedHeap.inline.hpp"28#include "gc/g1/g1GCParPhaseTimesTracker.hpp"29#include "runtime/atomic.hpp"30#include "utilities/growableArray.hpp"3132void G1AbstractSubTask::record_work_item(uint worker_id, uint index, size_t count) {33G1CollectedHeap* g1h = G1CollectedHeap::heap();34g1h->phase_times()->record_thread_work_item(_tag, worker_id, count, index);35}3637const char* G1AbstractSubTask::name() const {38G1CollectedHeap* g1h = G1CollectedHeap::heap();39return g1h->phase_times()->phase_name(_tag);40}4142bool G1BatchedGangTask::try_claim_serial_task(int& task) {43task = Atomic::fetch_and_add(&_num_serial_tasks_done, 1);44return task < _serial_tasks.length();45}4647void G1BatchedGangTask::add_serial_task(G1AbstractSubTask* task) {48assert(task != nullptr, "must be");49_serial_tasks.push(task);50}5152void G1BatchedGangTask::add_parallel_task(G1AbstractSubTask* task) {53assert(task != nullptr, "must be");54_parallel_tasks.push(task);55}5657G1BatchedGangTask::G1BatchedGangTask(const char* name, G1GCPhaseTimes* phase_times) :58AbstractGangTask(name),59_num_serial_tasks_done(0),60_phase_times(phase_times),61_serial_tasks(),62_parallel_tasks() {63}6465uint G1BatchedGangTask::num_workers_estimate() const {66double sum = 0.0;67for (G1AbstractSubTask* task : _serial_tasks) {68sum += task->worker_cost();69}70for (G1AbstractSubTask* task : _parallel_tasks) {71sum += task->worker_cost();72}73return ceil(sum);74}7576void G1BatchedGangTask::set_max_workers(uint max_workers) {77for (G1AbstractSubTask* task : _serial_tasks) {78task->set_max_workers(max_workers);79}80for (G1AbstractSubTask* task : _parallel_tasks) {81task->set_max_workers(max_workers);82}83}8485void G1BatchedGangTask::work(uint worker_id) {86int t = 0;87while (try_claim_serial_task(t)) {88G1AbstractSubTask* task = _serial_tasks.at(t);89G1GCParPhaseTimesTracker x(_phase_times, task->tag(), worker_id);90task->do_work(worker_id);91}92for (G1AbstractSubTask* task : _parallel_tasks) {93G1GCParPhaseTimesTracker x(_phase_times, task->tag(), worker_id);94task->do_work(worker_id);95}96}9798G1BatchedGangTask::~G1BatchedGangTask() {99assert(Atomic::load(&_num_serial_tasks_done) >= _serial_tasks.length(),100"Only %d tasks of %d claimed", Atomic::load(&_num_serial_tasks_done), _serial_tasks.length());101102for (G1AbstractSubTask* task : _parallel_tasks) {103delete task;104}105for (G1AbstractSubTask* task : _serial_tasks) {106delete task;107}108}109110111