Skip to content
This repository was archived by the owner on Feb 2, 2023. It is now read-only.
/ jdk13u-dev Public archive

Commit 92da5d8

Browse files
Ekaterina VergizovaYuri Nesterenko
Ekaterina Vergizova
authored and
Yuri Nesterenko
committed
8243489: Thread CPU Load event may contain wrong data for CPU time under certain conditions
Backport-of: 313758a
1 parent 91b19c9 commit 92da5d8

File tree

2 files changed

+82
-3
lines changed

2 files changed

+82
-3
lines changed

src/hotspot/share/jfr/periodic/jfrThreadCPULoadEvent.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -88,15 +88,14 @@ bool JfrThreadCPULoadEvent::update_event(EventThreadCPULoad& event, JavaThread*
8888
// Avoid reporting percentages above the theoretical max
8989
if (user_time + system_time > wallclock_time) {
9090
jlong excess = user_time + system_time - wallclock_time;
91+
cur_cpu_time -= excess;
9192
if (user_time > excess) {
9293
user_time -= excess;
9394
cur_user_time -= excess;
94-
cur_cpu_time -= excess;
9595
} else {
96-
cur_cpu_time -= excess;
9796
excess -= user_time;
97+
cur_user_time -= user_time;
9898
user_time = 0;
99-
cur_user_time = 0;
10099
system_time -= excess;
101100
}
102101
}

test/hotspot/gtest/jfr/test_threadCpuLoad.cpp

+80
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,12 @@ TEST_VM_F(JfrTestThreadCPULoadSingle, SingleCpu) {
140140
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, 400 * NANOSECS_PER_MILLISEC, 1));
141141
EXPECT_FLOAT_EQ(0.25, event.user);
142142
EXPECT_FLOAT_EQ(0.25, event.system);
143+
144+
MockOs::user_cpu_time += 50 * NANOSECS_PER_MILLISEC;
145+
MockOs::system_cpu_time += 50 * NANOSECS_PER_MILLISEC;
146+
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 400) * NANOSECS_PER_MILLISEC, 1));
147+
EXPECT_FLOAT_EQ(0.125, event.user);
148+
EXPECT_FLOAT_EQ(0.125, event.system);
143149
}
144150

145151
TEST_VM_F(JfrTestThreadCPULoadSingle, MultipleCpus) {
@@ -169,6 +175,43 @@ TEST_VM_F(JfrTestThreadCPULoadSingle, UserAboveMaximum) {
169175
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (200 + 400) * NANOSECS_PER_MILLISEC, 1));
170176
EXPECT_FLOAT_EQ(0.25, event.user);
171177
EXPECT_FLOAT_EQ(0, event.system);
178+
179+
// Third call: make sure there are no leftovers
180+
MockOs::user_cpu_time += 50 * NANOSECS_PER_MILLISEC;
181+
MockOs::system_cpu_time += 50 * NANOSECS_PER_MILLISEC;
182+
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (200 + 400 + 400) * NANOSECS_PER_MILLISEC, 1));
183+
EXPECT_FLOAT_EQ(0.125, event.user);
184+
EXPECT_FLOAT_EQ(0.125, event.system);
185+
}
186+
187+
TEST_VM_F(JfrTestThreadCPULoadSingle, UserAboveMaximumNonZeroBase) {
188+
189+
// Setup a non zero base
190+
// Previously there was a bug when cur_user_time would be reset to zero and test that uses zero base would fail to detect it
191+
MockOs::user_cpu_time = 100 * NANOSECS_PER_MILLISEC;
192+
MockOs::system_cpu_time = 100 * NANOSECS_PER_MILLISEC;
193+
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, 400 * NANOSECS_PER_MILLISEC, 1));
194+
EXPECT_FLOAT_EQ(0.25, event.user);
195+
EXPECT_FLOAT_EQ(0.25, event.system);
196+
197+
// First call will not report above 100%
198+
MockOs::user_cpu_time += 200 * NANOSECS_PER_MILLISEC;
199+
MockOs::system_cpu_time += 100 * NANOSECS_PER_MILLISEC;
200+
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 200) * NANOSECS_PER_MILLISEC, 1));
201+
EXPECT_FLOAT_EQ(0.5, event.user);
202+
EXPECT_FLOAT_EQ(0.5, event.system);
203+
204+
// Second call will see an extra 100 millisecs user time from the remainder
205+
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 200 + 400) * NANOSECS_PER_MILLISEC, 1));
206+
EXPECT_FLOAT_EQ(0.25, event.user);
207+
EXPECT_FLOAT_EQ(0, event.system);
208+
209+
// Third call: make sure there are no leftovers
210+
MockOs::user_cpu_time += 50 * NANOSECS_PER_MILLISEC;
211+
MockOs::system_cpu_time += 50 * NANOSECS_PER_MILLISEC;
212+
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 200 + 400 + 400) * NANOSECS_PER_MILLISEC, 1));
213+
EXPECT_FLOAT_EQ(0.125, event.user);
214+
EXPECT_FLOAT_EQ(0.125, event.system);
172215
}
173216

174217
TEST_VM_F(JfrTestThreadCPULoadSingle, SystemAboveMaximum) {
@@ -184,6 +227,43 @@ TEST_VM_F(JfrTestThreadCPULoadSingle, SystemAboveMaximum) {
184227
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (200 + 400) * NANOSECS_PER_MILLISEC, 1));
185228
EXPECT_FLOAT_EQ(0.25, event.user);
186229
EXPECT_FLOAT_EQ(0.25, event.system);
230+
231+
// Third call: make sure there are no leftovers
232+
MockOs::user_cpu_time += 50 * NANOSECS_PER_MILLISEC;
233+
MockOs::system_cpu_time += 50 * NANOSECS_PER_MILLISEC;
234+
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (200 + 400 + 400) * NANOSECS_PER_MILLISEC, 1));
235+
EXPECT_FLOAT_EQ(0.125, event.user);
236+
EXPECT_FLOAT_EQ(0.125, event.system);
237+
}
238+
239+
TEST_VM_F(JfrTestThreadCPULoadSingle, SystemAboveMaximumNonZeroBase) {
240+
241+
// Setup a non zero base
242+
// Previously there was a bug when cur_user_time would be reset to zero and test that uses zero base would fail to detect it
243+
MockOs::user_cpu_time = 100 * NANOSECS_PER_MILLISEC;
244+
MockOs::system_cpu_time = 100 * NANOSECS_PER_MILLISEC;
245+
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, 400 * NANOSECS_PER_MILLISEC, 1));
246+
EXPECT_FLOAT_EQ(0.25, event.user);
247+
EXPECT_FLOAT_EQ(0.25, event.system);
248+
249+
// First call will not report above 100%
250+
MockOs::user_cpu_time += 100 * NANOSECS_PER_MILLISEC;
251+
MockOs::system_cpu_time += 300 * NANOSECS_PER_MILLISEC;
252+
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 200) * NANOSECS_PER_MILLISEC, 1));
253+
EXPECT_FLOAT_EQ(0, event.user);
254+
EXPECT_FLOAT_EQ(1, event.system);
255+
256+
// Second call will see an extra 100 millisecs user and system time from the remainder
257+
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 200 + 400) * NANOSECS_PER_MILLISEC, 1));
258+
EXPECT_FLOAT_EQ(0.25, event.user);
259+
EXPECT_FLOAT_EQ(0.25, event.system);
260+
261+
// Third call: make sure there are no leftovers
262+
MockOs::user_cpu_time += 50 * NANOSECS_PER_MILLISEC;
263+
MockOs::system_cpu_time += 50 * NANOSECS_PER_MILLISEC;
264+
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 200 + 400 + 400) * NANOSECS_PER_MILLISEC, 1));
265+
EXPECT_FLOAT_EQ(0.125, event.user);
266+
EXPECT_FLOAT_EQ(0.125, event.system);
187267
}
188268

189269
TEST_VM_F(JfrTestThreadCPULoadSingle, SystemTimeDecreasing) {

0 commit comments

Comments
 (0)