8293623: Simplify G1ConcurrentRefineThreadControl

Reviewed-by: kbarrett, tschatzl
This commit is contained in:
Lei Zaakjyu 2023-12-21 15:20:01 +00:00 committed by Thomas Schatzl
parent 6de23bf36e
commit 1802601a12
2 changed files with 45 additions and 63 deletions

View File

@ -58,97 +58,77 @@ G1ConcurrentRefineThread* G1ConcurrentRefineThreadControl::create_refinement_thr
return result; return result;
} }
G1ConcurrentRefineThreadControl::G1ConcurrentRefineThreadControl() : G1ConcurrentRefineThreadControl::G1ConcurrentRefineThreadControl(uint max_num_threads) :
_cr(nullptr), _cr(nullptr),
_threads(nullptr), _threads(max_num_threads)
_max_num_threads(0)
{} {}
G1ConcurrentRefineThreadControl::~G1ConcurrentRefineThreadControl() { G1ConcurrentRefineThreadControl::~G1ConcurrentRefineThreadControl() {
if (_threads != nullptr) { while (_threads.is_nonempty()) {
for (uint i = 0; i < _max_num_threads; i++) { delete _threads.pop();
G1ConcurrentRefineThread* t = _threads[i];
if (t == nullptr) {
#ifdef ASSERT
for (uint j = i + 1; j < _max_num_threads; ++j) {
assert(_threads[j] == nullptr, "invariant");
}
#endif // ASSERT
break;
} else {
delete t;
}
}
FREE_C_HEAP_ARRAY(G1ConcurrentRefineThread*, _threads);
} }
} }
jint G1ConcurrentRefineThreadControl::initialize(G1ConcurrentRefine* cr, uint max_num_threads) { bool G1ConcurrentRefineThreadControl::ensure_threads_created(uint worker_id, bool initializing) {
assert(worker_id < max_num_threads(), "precondition");
while ((uint)_threads.length() <= worker_id) {
G1ConcurrentRefineThread* rt = create_refinement_thread(_threads.length(), initializing);
if (rt == nullptr) {
return false;
}
_threads.push(rt);
}
return true;
}
jint G1ConcurrentRefineThreadControl::initialize(G1ConcurrentRefine* cr) {
assert(cr != nullptr, "G1ConcurrentRefine must not be null"); assert(cr != nullptr, "G1ConcurrentRefine must not be null");
_cr = cr; _cr = cr;
_max_num_threads = max_num_threads;
if (max_num_threads > 0) { if (max_num_threads() > 0) {
_threads = NEW_C_HEAP_ARRAY(G1ConcurrentRefineThread*, max_num_threads, mtGC); _threads.push(create_refinement_thread(0, true));
if (_threads.at(0) == nullptr) {
_threads[0] = create_refinement_thread(0, true);
if (_threads[0] == nullptr) {
vm_shutdown_during_initialization("Could not allocate primary refinement thread"); vm_shutdown_during_initialization("Could not allocate primary refinement thread");
return JNI_ENOMEM; return JNI_ENOMEM;
} }
if (UseDynamicNumberOfGCThreads) { if (!UseDynamicNumberOfGCThreads) {
for (uint i = 1; i < max_num_threads; ++i) { if (!ensure_threads_created(max_num_threads() - 1, true)) {
_threads[i] = nullptr; vm_shutdown_during_initialization("Could not allocate refinement threads");
}
} else {
for (uint i = 1; i < max_num_threads; ++i) {
_threads[i] = create_refinement_thread(i, true);
if (_threads[i] == nullptr) {
vm_shutdown_during_initialization("Could not allocate refinement threads.");
return JNI_ENOMEM; return JNI_ENOMEM;
} }
} }
} }
}
return JNI_OK; return JNI_OK;
} }
#ifdef ASSERT #ifdef ASSERT
void G1ConcurrentRefineThreadControl::assert_current_thread_is_primary_refinement_thread() const { void G1ConcurrentRefineThreadControl::assert_current_thread_is_primary_refinement_thread() const {
assert(_threads != nullptr, "No threads"); assert(Thread::current() == _threads.at(0), "Not primary thread");
assert(Thread::current() == _threads[0], "Not primary thread");
} }
#endif // ASSERT #endif // ASSERT
bool G1ConcurrentRefineThreadControl::activate(uint worker_id) { bool G1ConcurrentRefineThreadControl::activate(uint worker_id) {
assert(worker_id < _max_num_threads, "precondition"); if (ensure_threads_created(worker_id, false)) {
G1ConcurrentRefineThread* thread_to_activate = _threads[worker_id]; _threads.at(worker_id)->activate();
if (thread_to_activate == nullptr) {
thread_to_activate = create_refinement_thread(worker_id, false);
if (thread_to_activate == nullptr) {
return false;
}
_threads[worker_id] = thread_to_activate;
}
thread_to_activate->activate();
return true; return true;
} }
void G1ConcurrentRefineThreadControl::worker_threads_do(ThreadClosure* tc) { return false;
for (uint i = 0; i < _max_num_threads; i++) {
if (_threads[i] != nullptr) {
tc->do_thread(_threads[i]);
} }
void G1ConcurrentRefineThreadControl::worker_threads_do(ThreadClosure* tc) {
for (G1ConcurrentRefineThread* t : _threads) {
tc->do_thread(t);
} }
} }
void G1ConcurrentRefineThreadControl::stop() { void G1ConcurrentRefineThreadControl::stop() {
for (uint i = 0; i < _max_num_threads; i++) { for (G1ConcurrentRefineThread* t : _threads) {
if (_threads[i] != nullptr) { t->stop();
_threads[i]->stop();
}
} }
} }
@ -170,12 +150,12 @@ G1ConcurrentRefine::G1ConcurrentRefine(G1Policy* policy) :
_last_adjust(), _last_adjust(),
_needs_adjust(false), _needs_adjust(false),
_threads_needed(policy, adjust_threads_period_ms()), _threads_needed(policy, adjust_threads_period_ms()),
_thread_control(), _thread_control(G1ConcRefinementThreads),
_dcqs(G1BarrierSet::dirty_card_queue_set()) _dcqs(G1BarrierSet::dirty_card_queue_set())
{} {}
jint G1ConcurrentRefine::initialize() { jint G1ConcurrentRefine::initialize() {
return _thread_control.initialize(this, G1ConcRefinementThreads); return _thread_control.initialize(this);
} }
G1ConcurrentRefine* G1ConcurrentRefine::create(G1Policy* policy, jint* ecode) { G1ConcurrentRefine* G1ConcurrentRefine::create(G1Policy* policy, jint* ecode) {

View File

@ -30,6 +30,7 @@
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
#include "utilities/debug.hpp" #include "utilities/debug.hpp"
#include "utilities/globalDefinitions.hpp" #include "utilities/globalDefinitions.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/macros.hpp" #include "utilities/macros.hpp"
// Forward decl // Forward decl
@ -43,24 +44,25 @@ class ThreadClosure;
// iterate over them. // iterate over them.
class G1ConcurrentRefineThreadControl { class G1ConcurrentRefineThreadControl {
G1ConcurrentRefine* _cr; G1ConcurrentRefine* _cr;
G1ConcurrentRefineThread** _threads; GrowableArrayCHeap<G1ConcurrentRefineThread*, mtGC> _threads;
uint _max_num_threads;
// Create the refinement thread for the given worker id. // Create the refinement thread for the given worker id.
// If initializing is true, ignore InjectGCWorkerCreationFailure. // If initializing is true, ignore InjectGCWorkerCreationFailure.
G1ConcurrentRefineThread* create_refinement_thread(uint worker_id, bool initializing); G1ConcurrentRefineThread* create_refinement_thread(uint worker_id, bool initializing);
bool ensure_threads_created(uint worker_id, bool initializing);
NONCOPYABLE(G1ConcurrentRefineThreadControl); NONCOPYABLE(G1ConcurrentRefineThreadControl);
public: public:
G1ConcurrentRefineThreadControl(); G1ConcurrentRefineThreadControl(uint max_num_threads);
~G1ConcurrentRefineThreadControl(); ~G1ConcurrentRefineThreadControl();
jint initialize(G1ConcurrentRefine* cr, uint max_num_threads); jint initialize(G1ConcurrentRefine* cr);
void assert_current_thread_is_primary_refinement_thread() const NOT_DEBUG_RETURN; void assert_current_thread_is_primary_refinement_thread() const NOT_DEBUG_RETURN;
uint max_num_threads() const { return _max_num_threads; } uint max_num_threads() const { return _threads.capacity(); }
// Activate the indicated thread. If the thread has not yet been allocated, // Activate the indicated thread. If the thread has not yet been allocated,
// allocate and then activate. If allocation is needed and fails, return // allocate and then activate. If allocation is needed and fails, return