Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/gtest/gc/g1/test_g1ServiceThread.cpp
41152 views
1
/*
2
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
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.
8
*
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).
14
*
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.
18
*
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
21
* questions.
22
*
23
*/
24
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"
31
32
class CheckTask : public G1ServiceTask {
33
int _execution_count;
34
bool _reschedule;
35
36
public:
37
CheckTask(const char* name) :
38
G1ServiceTask(name),
39
_execution_count(0),
40
_reschedule(true) { }
41
virtual void execute() {
42
_execution_count++;
43
if (_reschedule) {
44
schedule(100);
45
}
46
}
47
48
int execution_count() { return _execution_count;}
49
void set_reschedule(bool reschedule) { _reschedule = reschedule; }
50
};
51
52
static void stop_service_thread(G1ServiceThread* thread) {
53
ThreadInVMfromNative tvn(JavaThread::current());
54
thread->stop();
55
}
56
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);
62
63
CheckTask ct("AddAndRun");
64
st->register_task(&ct);
65
66
// Give CheckTask time to run.
67
os::naked_short_sleep(500);
68
stop_service_thread(st);
69
70
ASSERT_GT(ct.execution_count(), 0);
71
}
72
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);
79
AutoModifyRestore<uintx> f2(G1ConcRefinementServiceIntervalMillis, 100000);
80
81
// Create thread and let it start.
82
G1ServiceThread* st = new G1ServiceThread();
83
os::naked_short_sleep(500);
84
85
// Register a new task that should run right away.
86
CheckTask ct("AddWhileWaiting");
87
st->register_task(&ct);
88
89
// Give CheckTask time to run.
90
os::naked_short_sleep(500);
91
stop_service_thread(st);
92
93
ASSERT_GT(ct.execution_count(), 0);
94
}
95
96
// Test that a task with negative timeout is not rescheduled.
97
TEST_VM(G1ServiceThread, test_add_run_once) {
98
// Create thread and let it start.
99
G1ServiceThread* st = new G1ServiceThread();
100
os::naked_short_sleep(500);
101
102
// Set reschedule to false to only run once.
103
CheckTask ct("AddRunOnce");
104
ct.set_reschedule(false);
105
st->register_task(&ct);
106
107
// Give CheckTask time to run.
108
os::naked_short_sleep(500);
109
stop_service_thread(st);
110
111
// Should be exactly 1 since negative timeout should
112
// prevent rescheduling.
113
ASSERT_EQ(ct.execution_count(), 1);
114
}
115
116
class TestTask : public G1ServiceTask {
117
jlong _delay_ms;
118
public:
119
TestTask(jlong delay) :
120
G1ServiceTask("TestTask"),
121
_delay_ms(delay) {
122
set_time(delay);
123
}
124
virtual void execute() {}
125
void update_time(jlong now, int multiplier) {
126
set_time(now + (_delay_ms * multiplier));
127
}
128
};
129
130
TEST_VM(G1ServiceTaskQueue, add_ordered) {
131
G1ServiceTaskQueue queue;
132
133
int num_test_tasks = 5;
134
for (int i = 1; i <= num_test_tasks; i++) {
135
// Create tasks with different timeout.
136
TestTask* task = new TestTask(100 * i);
137
queue.add_ordered(task);
138
}
139
140
// Now fake a run-loop, that reschedules the tasks using a
141
// random multiplier.
142
for (jlong now = 0; now < 1000000; now++) {
143
// Random multiplier is at least 1 to ensure progress.
144
int multiplier = 1 + os::random() % 10;
145
while (queue.peek()->time() < now) {
146
TestTask* task = (TestTask*) queue.pop();
147
// Update delay multiplier.
148
task->execute();
149
task->update_time(now, multiplier);
150
// All additions will verify that the queue is sorted.
151
queue.add_ordered(task);
152
}
153
}
154
155
while (!queue.is_empty()) {
156
G1ServiceTask* task = queue.pop();
157
delete task;
158
}
159
}
160
161
#ifdef ASSERT
162
TEST_VM_ASSERT_MSG(G1ServiceTaskQueue, pop_empty,
163
".*Should never try to verify empty queue") {
164
G1ServiceTaskQueue queue;
165
queue.pop();
166
}
167
168
TEST_VM_ASSERT_MSG(G1ServiceTaskQueue, peek_empty,
169
".*Should never try to verify empty queue") {
170
G1ServiceTaskQueue queue;
171
queue.peek();
172
}
173
174
TEST_VM_ASSERT_MSG(G1ServiceTaskQueue, set_time_in_queue,
175
".*Not allowed to update time while in queue") {
176
G1ServiceTaskQueue queue;
177
TestTask a(100);
178
queue.add_ordered(&a);
179
// Not allowed to update time while in queue.
180
a.update_time(500, 1);
181
}
182
183
#endif
184
185