8255980: G1 Service thread register_task can be used after shutdown
Reviewed-by: tschatzl, ayang
This commit is contained in:
parent
dd8e4ffbe5
commit
79b7909507
src/hotspot/share/gc/g1
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user