/* * Copyright (c) 2001, 2022, 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. *
*/
// The (single) primary thread drives the controller for the refinement threads. class G1PrimaryConcurrentRefineThread final : public G1ConcurrentRefineThread { bool wait_for_completed_buffers() override; bool maybe_deactivate() override; void do_refinement_step() override;
// When inactive, the primary thread periodically wakes up and requests // adjustment of the number of active refinement threads. bool G1PrimaryConcurrentRefineThread::wait_for_completed_buffers() {
assert(this == Thread::current(), "precondition");
MonitorLocker ml(notifier(), Mutex::_no_safepoint_check_flag); if (!requested_active() && !should_terminate()) { // Rather than trying to be smart about spurious wakeups, we just treat // them as timeouts.
ml.wait(cr()->adjust_threads_wait_ms());
} // Record adjustment needed whenever reactivating.
cr()->record_thread_adjustment_needed(); return !should_terminate();
}
bool G1PrimaryConcurrentRefineThread::maybe_deactivate() { // Don't deactivate while needing to adjust the number of active threads. return !cr()->is_thread_adjustment_needed() &&
G1ConcurrentRefineThread::maybe_deactivate();
}
void G1PrimaryConcurrentRefineThread::do_refinement_step() { // Try adjustment first. If it succeeds then don't do any refinement this // round. This thread may have just woken up but no threads are currently // needed, which is common. In this case we want to just go back to // waiting, with a minimum of fuss; in particular, don't do any "premature" // refinement. However, adjustment may be pending but temporarily // blocked. In that case we *do* try refinement, rather than possibly // uselessly spinning while waiting for adjustment to succeed. if (!cr()->adjust_threads_periodically()) { // No adjustment, so try refinement, with the target as a cuttoff. if (!try_refinement_step(cr()->pending_cards_target())) { // Refinement was cut off, so proceed with fewer threads.
cr()->reduce_threads_wanted();
}
}
}
class G1SecondaryConcurrentRefineThread final : public G1ConcurrentRefineThread { bool wait_for_completed_buffers() override; void do_refinement_step() override;
void G1SecondaryConcurrentRefineThread::do_refinement_step() {
assert(this == Thread::current(), "precondition"); // Secondary threads ignore the target and just drive the number of pending // dirty cards down. The primary thread is responsible for noticing the // target has been reached and reducing the number of wanted threads. This // makes the control of wanted threads all under the primary, while avoiding // useless spinning by secondary threads until the primary thread notices. // (Useless spinning is still possible if there are no pending cards, but // that should rarely happen.)
try_refinement_step(0);
}
G1ConcurrentRefineThread*
G1ConcurrentRefineThread::create(G1ConcurrentRefine* cr, uint worker_id) {
G1ConcurrentRefineThread* crt; if (worker_id == 0) {
crt = new (std::nothrow) G1PrimaryConcurrentRefineThread(cr);
} else {
crt = new (std::nothrow) G1SecondaryConcurrentRefineThread(cr, worker_id);
} if (crt != nullptr) {
crt->create_and_start();
} return crt;
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.