8255980: G1 Service thread register_task can be used after shutdown

Reviewed-by: tschatzl, ayang
This commit is contained in:
Stefan Johansson 2020-11-09 14:24:24 +00:00
parent dd8e4ffbe5
commit 79b7909507
2 changed files with 27 additions and 7 deletions

@ -176,15 +176,30 @@ G1ServiceThread::G1ServiceThread() :
true,
Monitor::_safepoint_check_never),
_task_queue(),
_remset_task(new G1RemSetSamplingTask("Remembered Set Sampling Task")),
_periodic_gc_task(new G1PeriodicGCTask("Periodic GC Task")),
_vtime_accum(0) {
set_name("G1 Service");
create_and_start();
}
G1ServiceThread::~G1ServiceThread() {
delete _remset_task;
delete _periodic_gc_task;
}
void G1ServiceThread::register_task(G1ServiceTask* task, jlong delay) {
guarantee(!task->is_registered(), "Task already registered");
guarantee(task->next() == NULL, "Task already in queue");
// Make sure the service thread is still up and running, there is a race
// during shutdown where the service thread has been stopped, but other
// GC threads might still be running and trying to add tasks.
if (has_terminated()) {
log_debug(gc, task)("G1 Service Thread (%s) (terminated)", task->name());
return;
}
log_debug(gc, task)("G1 Service Thread (%s) (register)", task->name());
// Associate the task with the service thread.
@ -272,13 +287,9 @@ void G1ServiceThread::run_task(G1ServiceTask* task) {
void G1ServiceThread::run_service() {
double vtime_start = os::elapsedVTime();
// Setup the tasks handeled by the service thread and
// add them to the task list.
G1PeriodicGCTask gc_task("Periodic GC Task");
register_task(&gc_task);
G1RemSetSamplingTask remset_task("Remembered Set Sampling Task");
register_task(&remset_task);
// Register the tasks handled by the service thread.
register_task(_periodic_gc_task);
register_task(_remset_task);
while (!should_terminate()) {
G1ServiceTask* task = pop_due_task();
@ -293,6 +304,8 @@ void G1ServiceThread::run_service() {
}
sleep_before_next_cycle();
}
log_debug(gc, task)("G1 Service Thread (stopping)");
}
void G1ServiceThread::stop_service() {

@ -28,6 +28,8 @@
#include "gc/shared/concurrentGCThread.hpp"
#include "runtime/mutex.hpp"
class G1PeriodicGCTask;
class G1RemSetSamplingTask;
class G1ServiceTaskQueue;
class G1ServiceThread;
@ -103,6 +105,9 @@ class G1ServiceThread: public ConcurrentGCThread {
Monitor _monitor;
G1ServiceTaskQueue _task_queue;
G1RemSetSamplingTask* _remset_task;
G1PeriodicGCTask* _periodic_gc_task;
double _vtime_accum; // Accumulated virtual time.
void run_service();
@ -122,6 +127,8 @@ class G1ServiceThread: public ConcurrentGCThread {
public:
G1ServiceThread();
~G1ServiceThread();
double vtime_accum() { return _vtime_accum; }
// Register a task with the service thread and schedule it. If
// no delay is specified the task is scheduled to run directly.