2
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
25
#include "precompiled.hpp"
26
#include "gc/g1/g1ServiceThread.hpp"
27
#include "runtime/interfaceSupport.inline.hpp"
28
#include "runtime/os.hpp"
29
#include "utilities/autoRestore.hpp"
30
#include "unittest.hpp"
32
class CheckTask : public G1ServiceTask {
37
CheckTask(const char* name) :
41
virtual void execute() {
48
int execution_count() { return _execution_count;}
49
void set_reschedule(bool reschedule) { _reschedule = reschedule; }
52
static void stop_service_thread(G1ServiceThread* thread) {
53
ThreadInVMfromNative tvn(JavaThread::current());
57
// Test that a task that is added during runtime gets run.
58
TEST_VM(G1ServiceThread, test_add) {
59
// Create thread and let it start.
60
G1ServiceThread* st = new G1ServiceThread();
61
os::naked_short_sleep(500);
63
CheckTask ct("AddAndRun");
64
st->register_task(&ct);
66
// Give CheckTask time to run.
67
os::naked_short_sleep(500);
68
stop_service_thread(st);
70
ASSERT_GT(ct.execution_count(), 0);
73
// Test that a task that is added while the service thread is
74
// waiting gets run in a timely manner.
75
TEST_VM(G1ServiceThread, test_add_while_waiting) {
76
// Make sure default tasks use long intervals so that the service thread
77
// is doing a long wait for the next execution.
78
AutoModifyRestore<uintx> f1(G1PeriodicGCInterval, 100000);
80
// Create thread and let it start.
81
G1ServiceThread* st = new G1ServiceThread();
82
os::naked_short_sleep(500);
84
// Register a new task that should run right away.
85
CheckTask ct("AddWhileWaiting");
86
st->register_task(&ct);
88
// Give CheckTask time to run.
89
os::naked_short_sleep(500);
90
stop_service_thread(st);
92
ASSERT_GT(ct.execution_count(), 0);
95
// Test that a task with negative timeout is not rescheduled.
96
TEST_VM(G1ServiceThread, test_add_run_once) {
97
// Create thread and let it start.
98
G1ServiceThread* st = new G1ServiceThread();
99
os::naked_short_sleep(500);
101
// Set reschedule to false to only run once.
102
CheckTask ct("AddRunOnce");
103
ct.set_reschedule(false);
104
st->register_task(&ct);
106
// Give CheckTask time to run.
107
os::naked_short_sleep(500);
108
stop_service_thread(st);
110
// Should be exactly 1 since negative timeout should
111
// prevent rescheduling.
112
ASSERT_EQ(ct.execution_count(), 1);
115
class TestTask : public G1ServiceTask {
118
TestTask(jlong delay) :
119
G1ServiceTask("TestTask"),
123
virtual void execute() {}
124
void update_time(jlong now, int multiplier) {
125
set_time(now + (_delay_ms * multiplier));
129
TEST_VM(G1ServiceTaskQueue, add_ordered) {
130
G1ServiceTaskQueue queue;
132
int num_test_tasks = 5;
133
for (int i = 1; i <= num_test_tasks; i++) {
134
// Create tasks with different timeout.
135
TestTask* task = new TestTask(100 * i);
136
queue.add_ordered(task);
139
// Now fake a run-loop, that reschedules the tasks using a
140
// random multiplier.
141
for (jlong now = 0; now < 1000000; now++) {
142
// Random multiplier is at least 1 to ensure progress.
143
int multiplier = 1 + os::random() % 10;
144
while (queue.front()->time() < now) {
145
TestTask* task = (TestTask*) queue.front();
146
queue.remove_front();
147
// Update delay multiplier.
149
task->update_time(now, multiplier);
150
// All additions will verify that the queue is sorted.
151
queue.add_ordered(task);
155
while (!queue.is_empty()) {
156
G1ServiceTask* task = queue.front();
157
queue.remove_front();
163
TEST_VM_ASSERT_MSG(G1ServiceTaskQueue, remove_from_empty,
164
".*Should never try to verify empty queue") {
165
G1ServiceTaskQueue queue;
166
queue.remove_front();
169
TEST_VM_ASSERT_MSG(G1ServiceTaskQueue, get_from_empty,
170
".*Should never try to verify empty queue") {
171
G1ServiceTaskQueue queue;
175
TEST_VM_ASSERT_MSG(G1ServiceTaskQueue, set_time_in_queue,
176
".*Not allowed to update time while in queue") {
177
G1ServiceTaskQueue queue;
179
queue.add_ordered(&a);
180
// Not allowed to update time while in queue.
181
a.update_time(500, 1);