Skip to content

Commit

Permalink
8280917: Simplify G1ConcurrentRefineThread activation
Browse files Browse the repository at this point in the history
Reviewed-by: iwalulya, sjohanss
  • Loading branch information
Kim Barrett committed Feb 8, 2022
1 parent f2a9627 commit 861f279
Show file tree
Hide file tree
Showing 7 changed files with 300 additions and 152 deletions.
8 changes: 1 addition & 7 deletions src/hotspot/share/gc/g1/g1CollectedHeap.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved.
* 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
Expand Down Expand Up @@ -1726,12 +1726,6 @@ jint G1CollectedHeap::initialize() {
_free_segmented_array_memory_task = new G1SegmentedArrayFreeMemoryTask("Card Set Free Memory Task");
_service_thread->register_task(_free_segmented_array_memory_task);

{
G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
dcqs.set_process_cards_threshold(concurrent_refine()->yellow_zone());
dcqs.set_max_cards(concurrent_refine()->red_zone());
}

// Here we allocate the dummy HeapRegion that is required by the
// G1AllocRegion class.
HeapRegion* dummy_region = _hrm.get_dummy_region();
Expand Down
68 changes: 42 additions & 26 deletions src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved.
* 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
Expand Down Expand Up @@ -42,7 +42,7 @@
G1ConcurrentRefineThread* G1ConcurrentRefineThreadControl::create_refinement_thread(uint worker_id, bool initializing) {
G1ConcurrentRefineThread* result = NULL;
if (initializing || !InjectGCWorkerCreationFailure) {
result = new G1ConcurrentRefineThread(_cr, worker_id);
result = G1ConcurrentRefineThread::create(_cr, worker_id);
}
if (result == NULL || result->osthread() == NULL) {
log_warning(gc)("Failed to create refinement thread %u, no more %s",
Expand All @@ -53,8 +53,9 @@ G1ConcurrentRefineThread* G1ConcurrentRefineThreadControl::create_refinement_thr
}

G1ConcurrentRefineThreadControl::G1ConcurrentRefineThreadControl() :
_cr(NULL),
_threads(NULL),
_cr(nullptr),
_primary_thread(nullptr),
_threads(nullptr),
_num_max_threads(0)
{
}
Expand All @@ -76,22 +77,27 @@ jint G1ConcurrentRefineThreadControl::initialize(G1ConcurrentRefine* cr, uint nu

_threads = NEW_C_HEAP_ARRAY(G1ConcurrentRefineThread*, num_max_threads, mtGC);

for (uint i = 0; i < num_max_threads; i++) {
if (UseDynamicNumberOfGCThreads && i != 0 /* Always start first thread. */) {
_threads[i] = NULL;
} else {
_threads[i] = create_refinement_thread(i, true);
if (_threads[i] == NULL) {
vm_shutdown_during_initialization("Could not allocate refinement threads.");
return JNI_ENOMEM;
if (num_max_threads > 0) {
auto primary = G1PrimaryConcurrentRefineThread::create(cr);
if (primary == nullptr) {
vm_shutdown_during_initialization("Could not allocate primary refinement thread");
return JNI_ENOMEM;
}
_threads[0] = _primary_thread = primary;

for (uint i = 1; i < num_max_threads; ++i) {
if (UseDynamicNumberOfGCThreads) {
_threads[i] = nullptr;
} else {
_threads[i] = create_refinement_thread(i, true);
if (_threads[i] == nullptr) {
vm_shutdown_during_initialization("Could not allocate refinement threads.");
return JNI_ENOMEM;
}
}
}
}

if (num_max_threads > 0) {
G1BarrierSet::dirty_card_queue_set().set_primary_refinement_thread(_threads[0]);
}

return JNI_OK;
}

Expand Down Expand Up @@ -237,7 +243,18 @@ G1ConcurrentRefine::G1ConcurrentRefine(size_t green_zone,
}

jint G1ConcurrentRefine::initialize() {
return _thread_control.initialize(this, max_num_threads());
jint result = _thread_control.initialize(this, max_num_threads());
if (result != JNI_OK) return result;

G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
dcqs.set_max_cards(red_zone());
if (max_num_threads() > 0) {
G1PrimaryConcurrentRefineThread* primary_thread = _thread_control.primary_thread();
primary_thread->update_notify_threshold(primary_activation_threshold());
dcqs.set_refinement_notification_thread(primary_thread);
}

return JNI_OK;
}

static size_t calc_min_yellow_zone_size() {
Expand Down Expand Up @@ -392,14 +409,9 @@ void G1ConcurrentRefine::adjust(double logged_cards_scan_time,
update_zones(logged_cards_scan_time, processed_logged_cards, goal_ms);

// Change the barrier params
if (max_num_threads() == 0) {
// Disable dcqs notification when there are no threads to notify.
dcqs.set_process_cards_threshold(G1DirtyCardQueueSet::ProcessCardsThresholdNever);
} else {
// Worker 0 is the primary; wakeup is via dcqs notification.
STATIC_ASSERT(max_yellow_zone <= INT_MAX);
size_t activate = activation_threshold(0);
dcqs.set_process_cards_threshold(activate);
if (max_num_threads() > 0) {
size_t threshold = primary_activation_threshold();
_thread_control.primary_thread()->update_notify_threshold(threshold);
}
dcqs.set_max_cards(red_zone());
}
Expand All @@ -411,7 +423,6 @@ void G1ConcurrentRefine::adjust(double logged_cards_scan_time,
} else {
dcqs.set_max_cards_padding(0);
}
dcqs.notify_if_necessary();
}

G1ConcurrentRefineStats G1ConcurrentRefine::get_and_reset_refinement_stats() {
Expand All @@ -438,6 +449,11 @@ size_t G1ConcurrentRefine::deactivation_threshold(uint worker_id) const {
return deactivation_level(thresholds);
}

size_t G1ConcurrentRefine::primary_activation_threshold() const {
assert(max_num_threads() > 0, "No primary refinement thread");
return activation_threshold(0);
}

uint G1ConcurrentRefine::worker_id_offset() {
return G1DirtyCardQueueSet::num_par_ids();
}
Expand Down
18 changes: 14 additions & 4 deletions src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
* 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
Expand Down Expand Up @@ -27,20 +27,20 @@

#include "gc/g1/g1ConcurrentRefineStats.hpp"
#include "memory/allocation.hpp"
#include "utilities/debug.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/ticks.hpp"

// Forward decl
class G1ConcurrentRefine;
class G1ConcurrentRefineThread;
class outputStream;
class G1PrimaryConcurrentRefineThread;
class ThreadClosure;

// Helper class for refinement thread management. Used to start, stop and
// iterate over them.
class G1ConcurrentRefineThreadControl {
G1ConcurrentRefine* _cr;

G1PrimaryConcurrentRefineThread* _primary_thread;
G1ConcurrentRefineThread** _threads;
uint _num_max_threads;

Expand All @@ -53,6 +53,12 @@ class G1ConcurrentRefineThreadControl {

jint initialize(G1ConcurrentRefine* cr, uint num_max_threads);

G1PrimaryConcurrentRefineThread* primary_thread() const {
assert(_num_max_threads > 0, "precondition");
assert(_primary_thread != nullptr, "uninitialized");
return _primary_thread;
}

// If there is a "successor" thread that can be activated given the current id,
// activate it.
void maybe_activate_next(uint cur_worker_id);
Expand Down Expand Up @@ -116,6 +122,10 @@ class G1ConcurrentRefine : public CHeapObj<mtGC> {

void stop();

// The minimum number of pending cards for activation of the primary
// refinement thread.
size_t primary_activation_threshold() const;

// Adjust refinement thresholds based on work done during the pause and the goal time.
void adjust(double logged_cards_scan_time, size_t processed_logged_cards, double goal_ms);

Expand Down
Loading

1 comment on commit 861f279

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.