Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
8257149: Improve G1 Service thread task scheduling to guarantee task …
…delay

Reviewed-by: sjohanss, iwalulya
  • Loading branch information
albertnetymk authored and kstefanj committed Nov 27, 2020
1 parent f2f3ba9 commit 20525d2
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 20 deletions.
12 changes: 3 additions & 9 deletions src/hotspot/share/gc/g1/g1RemSet.cpp
Expand Up @@ -558,12 +558,6 @@ class G1RemSetSamplingTask : public G1ServiceTask {
update_vtime_accum(vtime.duration());
}

// To avoid extensive rescheduling if the task is executed a bit early. The task is
// only rescheduled if the expected time is more than 1ms away.
bool should_reschedule() {
return reschedule_delay_ms() > 1;
}

// There is no reason to do the sampling if a GC occurred recently. We use the
// G1ConcRefinementServiceIntervalMillis as the metric for recently and calculate
// the diff to the last GC. If the last GC occurred longer ago than the interval
Expand All @@ -580,9 +574,9 @@ class G1RemSetSamplingTask : public G1ServiceTask {
SuspendibleThreadSetJoiner sts;

// Reschedule if a GC happened too recently.
if (should_reschedule()) {
// Calculate the delay given the last GC and the interval.
schedule(reschedule_delay_ms());
jlong delay_ms = reschedule_delay_ms();
if (delay_ms > 0) {
schedule(delay_ms);
return;
}

Expand Down
9 changes: 5 additions & 4 deletions src/hotspot/share/gc/g1/g1ServiceThread.cpp
Expand Up @@ -111,7 +111,7 @@ G1ServiceThread::~G1ServiceThread() {
delete _periodic_gc_task;
}

void G1ServiceThread::register_task(G1ServiceTask* task, jlong delay) {
void G1ServiceThread::register_task(G1ServiceTask* task, jlong delay_ms) {
guarantee(!task->is_registered(), "Task already registered");
guarantee(task->next() == NULL, "Task already in queue");

Expand All @@ -130,7 +130,7 @@ void G1ServiceThread::register_task(G1ServiceTask* task, jlong delay) {

// Schedule the task to run after the given delay. The service will be
// notified to check if this task is first in the queue.
schedule_task(task, delay);
schedule_task(task, delay_ms);
}

void G1ServiceThread::schedule(G1ServiceTask* task, jlong delay_ms) {
Expand Down Expand Up @@ -163,8 +163,9 @@ int64_t G1ServiceThread::time_to_next_task_ms() {
return 0;
}

// Return sleep time in milliseconds.
return (int64_t) TimeHelper::counter_to_millis(time_diff);
// Return sleep time in milliseconds. Using ceil to make sure we never
// schedule a task too early.
return (int64_t) ceil(TimeHelper::counter_to_millis(time_diff));
}

void G1ServiceThread::notify() {
Expand Down
15 changes: 8 additions & 7 deletions src/hotspot/share/gc/g1/g1ServiceThread.hpp
Expand Up @@ -131,13 +131,14 @@ class G1ServiceThread: public ConcurrentGCThread {
G1ServiceThread();
~G1ServiceThread();

// Register a task with the service thread and schedule it. If
// no delay is specified the task is scheduled to run directly.
void register_task(G1ServiceTask* task, jlong delay = 0);

// Schedule the task and notify the service thread that a new
// task might be ready to run.
void schedule_task(G1ServiceTask* task, jlong delay);
// Register a task with the service thread. The task is guaranteed not to run
// until at least `delay_ms` has passed. If no delay is specified or the
// delay is 0, the task will run in the earliest time possible.
void register_task(G1ServiceTask* task, jlong delay_ms = 0);

// Schedule an already-registered task to run in at least `delay_ms` time,
// and notify the service thread.
void schedule_task(G1ServiceTask* task, jlong delay_ms);
};

#endif // SHARE_GC_G1_G1SERVICETHREAD_HPP

1 comment on commit 20525d2

@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.