Skip to content
Permalink
Browse files
8243489: Thread CPU Load event may contain wrong data for CPU time un…
…der certain conditions

Backport-of: 313758a
  • Loading branch information
Ekaterina Vergizova authored and Yuri Nesterenko committed Nov 26, 2020
1 parent 91b19c9 commit 92da5d8fd867554880a1903d889ffc7745a79774
Showing 2 changed files with 82 additions and 3 deletions.
@@ -88,15 +88,14 @@ bool JfrThreadCPULoadEvent::update_event(EventThreadCPULoad& event, JavaThread*
// Avoid reporting percentages above the theoretical max
if (user_time + system_time > wallclock_time) {
jlong excess = user_time + system_time - wallclock_time;
cur_cpu_time -= excess;
if (user_time > excess) {
user_time -= excess;
cur_user_time -= excess;
cur_cpu_time -= excess;
} else {
cur_cpu_time -= excess;
excess -= user_time;
cur_user_time -= user_time;
user_time = 0;
cur_user_time = 0;
system_time -= excess;
}
}
@@ -140,6 +140,12 @@ TEST_VM_F(JfrTestThreadCPULoadSingle, SingleCpu) {
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, 400 * NANOSECS_PER_MILLISEC, 1));
EXPECT_FLOAT_EQ(0.25, event.user);
EXPECT_FLOAT_EQ(0.25, event.system);

MockOs::user_cpu_time += 50 * NANOSECS_PER_MILLISEC;
MockOs::system_cpu_time += 50 * NANOSECS_PER_MILLISEC;
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 400) * NANOSECS_PER_MILLISEC, 1));
EXPECT_FLOAT_EQ(0.125, event.user);
EXPECT_FLOAT_EQ(0.125, event.system);
}

TEST_VM_F(JfrTestThreadCPULoadSingle, MultipleCpus) {
@@ -169,6 +175,43 @@ TEST_VM_F(JfrTestThreadCPULoadSingle, UserAboveMaximum) {
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (200 + 400) * NANOSECS_PER_MILLISEC, 1));
EXPECT_FLOAT_EQ(0.25, event.user);
EXPECT_FLOAT_EQ(0, event.system);

// Third call: make sure there are no leftovers
MockOs::user_cpu_time += 50 * NANOSECS_PER_MILLISEC;
MockOs::system_cpu_time += 50 * NANOSECS_PER_MILLISEC;
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (200 + 400 + 400) * NANOSECS_PER_MILLISEC, 1));
EXPECT_FLOAT_EQ(0.125, event.user);
EXPECT_FLOAT_EQ(0.125, event.system);
}

TEST_VM_F(JfrTestThreadCPULoadSingle, UserAboveMaximumNonZeroBase) {

// Setup a non zero base
// 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
MockOs::user_cpu_time = 100 * NANOSECS_PER_MILLISEC;
MockOs::system_cpu_time = 100 * NANOSECS_PER_MILLISEC;
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, 400 * NANOSECS_PER_MILLISEC, 1));
EXPECT_FLOAT_EQ(0.25, event.user);
EXPECT_FLOAT_EQ(0.25, event.system);

// First call will not report above 100%
MockOs::user_cpu_time += 200 * NANOSECS_PER_MILLISEC;
MockOs::system_cpu_time += 100 * NANOSECS_PER_MILLISEC;
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 200) * NANOSECS_PER_MILLISEC, 1));
EXPECT_FLOAT_EQ(0.5, event.user);
EXPECT_FLOAT_EQ(0.5, event.system);

// Second call will see an extra 100 millisecs user time from the remainder
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 200 + 400) * NANOSECS_PER_MILLISEC, 1));
EXPECT_FLOAT_EQ(0.25, event.user);
EXPECT_FLOAT_EQ(0, event.system);

// Third call: make sure there are no leftovers
MockOs::user_cpu_time += 50 * NANOSECS_PER_MILLISEC;
MockOs::system_cpu_time += 50 * NANOSECS_PER_MILLISEC;
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 200 + 400 + 400) * NANOSECS_PER_MILLISEC, 1));
EXPECT_FLOAT_EQ(0.125, event.user);
EXPECT_FLOAT_EQ(0.125, event.system);
}

TEST_VM_F(JfrTestThreadCPULoadSingle, SystemAboveMaximum) {
@@ -184,6 +227,43 @@ TEST_VM_F(JfrTestThreadCPULoadSingle, SystemAboveMaximum) {
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (200 + 400) * NANOSECS_PER_MILLISEC, 1));
EXPECT_FLOAT_EQ(0.25, event.user);
EXPECT_FLOAT_EQ(0.25, event.system);

// Third call: make sure there are no leftovers
MockOs::user_cpu_time += 50 * NANOSECS_PER_MILLISEC;
MockOs::system_cpu_time += 50 * NANOSECS_PER_MILLISEC;
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (200 + 400 + 400) * NANOSECS_PER_MILLISEC, 1));
EXPECT_FLOAT_EQ(0.125, event.user);
EXPECT_FLOAT_EQ(0.125, event.system);
}

TEST_VM_F(JfrTestThreadCPULoadSingle, SystemAboveMaximumNonZeroBase) {

// Setup a non zero base
// 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
MockOs::user_cpu_time = 100 * NANOSECS_PER_MILLISEC;
MockOs::system_cpu_time = 100 * NANOSECS_PER_MILLISEC;
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, 400 * NANOSECS_PER_MILLISEC, 1));
EXPECT_FLOAT_EQ(0.25, event.user);
EXPECT_FLOAT_EQ(0.25, event.system);

// First call will not report above 100%
MockOs::user_cpu_time += 100 * NANOSECS_PER_MILLISEC;
MockOs::system_cpu_time += 300 * NANOSECS_PER_MILLISEC;
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 200) * NANOSECS_PER_MILLISEC, 1));
EXPECT_FLOAT_EQ(0, event.user);
EXPECT_FLOAT_EQ(1, event.system);

// Second call will see an extra 100 millisecs user and system time from the remainder
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 200 + 400) * NANOSECS_PER_MILLISEC, 1));
EXPECT_FLOAT_EQ(0.25, event.user);
EXPECT_FLOAT_EQ(0.25, event.system);

// Third call: make sure there are no leftovers
MockOs::user_cpu_time += 50 * NANOSECS_PER_MILLISEC;
MockOs::system_cpu_time += 50 * NANOSECS_PER_MILLISEC;
EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 200 + 400 + 400) * NANOSECS_PER_MILLISEC, 1));
EXPECT_FLOAT_EQ(0.125, event.user);
EXPECT_FLOAT_EQ(0.125, event.system);
}

TEST_VM_F(JfrTestThreadCPULoadSingle, SystemTimeDecreasing) {

1 comment on commit 92da5d8

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on 92da5d8 Nov 26, 2020

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.