Path: blob/master/test/hotspot/gtest/jfr/test_threadCpuLoad.cpp
41144 views
/*1* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"2526// This test performs mocking of certain JVM functionality. This works by27// including the source file under test inside an anonymous namespace (which28// prevents linking conflicts) with the mocked symbols redefined.2930// The include list should mirror the one found in the included source file -31// with the ones that should pick up the mocks removed. Those should be included32// later after the mocks have been defined.3334#include "logging/log.hpp"35#include "jfr/jfrEvents.hpp"36#include "jfr/support/jfrThreadId.hpp"37#include "jfr/support/jfrThreadLocal.hpp"38#include "jfr/utilities/jfrThreadIterator.hpp"39#include "jfr/utilities/jfrTime.hpp"40#include "utilities/globalDefinitions.hpp"41#include "runtime/os.hpp"4243#include "unittest.hpp"4445namespace {4647class MockEventThreadCPULoad : public ::EventThreadCPULoad48{49public:50float user;51float system;5253public:54MockEventThreadCPULoad(EventStartTime timing=TIMED) : ::EventThreadCPULoad(timing) {}5556void set_user(float new_value) {57user = new_value;58}59void set_system(float new_value) {60system = new_value;61}62};6364class MockOs : public ::os {65public:66static jlong user_cpu_time;67static jlong system_cpu_time;6869static jlong thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {70return user_sys_cpu_time ? user_cpu_time + system_cpu_time : user_cpu_time;71}72};7374jlong MockOs::user_cpu_time;75jlong MockOs::system_cpu_time;7677class MockJavaThread : public ::JavaThread {78public:79MockJavaThread() : ::JavaThread() {}80};8182class MockJfrJavaThreadIterator83{84public:85MockJavaThread* next() { return NULL; }86bool has_next() const { return false; }87};8889class MockJfrJavaThreadIteratorAdapter90{91public:92MockJavaThread* next() { return NULL; }93bool has_next() const { return false; }94};9596// Reincluding source files in the anonymous namespace unfortunately seems to97// behave strangely with precompiled headers (only when using gcc though)98#ifndef DONT_USE_PRECOMPILED_HEADER99#define DONT_USE_PRECOMPILED_HEADER100#endif101102#define os MockOs103#define EventThreadCPULoad MockEventThreadCPULoad104#define JavaThread MockJavaThread105#define JfrJavaThreadIterator MockJfrJavaThreadIterator106#define JfrJavaThreadIteratorAdapter MockJfrJavaThreadIteratorAdapter107108#include "jfr/periodic/jfrThreadCPULoadEvent.hpp"109#include "jfr/periodic/jfrThreadCPULoadEvent.cpp"110111#undef os112#undef EventThreadCPULoad113#undef JavaThread114#define JfrJavaThreadIterator MockJfrJavaThreadIterator115#define JfrJavaThreadIteratorAdapter MockJfrJavaThreadIteratorAdapter116117} // anonymous namespace118119class JfrTestThreadCPULoadSingle : public ::testing::Test {120protected:121MockJavaThread* thread;122JfrThreadLocal* thread_data;123MockEventThreadCPULoad event;124125void SetUp() {126thread = new MockJavaThread();127thread_data = thread->jfr_thread_local();128thread_data->set_wallclock_time(0);129thread_data->set_user_time(0);130thread_data->set_cpu_time(0);131}132133void TearDown() {134delete thread;135}136137// Fix for gcc compilation warning about unused functions138bool TouchUnused() {139return (&JfrThreadCPULoadEvent::send_events &&140&JfrThreadCPULoadEvent::send_event_for_thread);141}142};143144TEST_VM_F(JfrTestThreadCPULoadSingle, SingleCpu) {145MockOs::user_cpu_time = 100 * NANOSECS_PER_MILLISEC;146MockOs::system_cpu_time = 100 * NANOSECS_PER_MILLISEC;147EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, 400 * NANOSECS_PER_MILLISEC, 1));148EXPECT_FLOAT_EQ(0.25, event.user);149EXPECT_FLOAT_EQ(0.25, event.system);150151MockOs::user_cpu_time += 50 * NANOSECS_PER_MILLISEC;152MockOs::system_cpu_time += 50 * NANOSECS_PER_MILLISEC;153EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 400) * NANOSECS_PER_MILLISEC, 1));154EXPECT_FLOAT_EQ(0.125, event.user);155EXPECT_FLOAT_EQ(0.125, event.system);156}157158TEST_VM_F(JfrTestThreadCPULoadSingle, MultipleCpus) {159MockOs::user_cpu_time = 100 * NANOSECS_PER_MILLISEC;160MockOs::system_cpu_time = 100 * NANOSECS_PER_MILLISEC;161EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, 400 * NANOSECS_PER_MILLISEC, 2));162EXPECT_FLOAT_EQ(0.125, event.user);163EXPECT_FLOAT_EQ(0.125, event.system);164}165166TEST_VM_F(JfrTestThreadCPULoadSingle, BelowThreshold) {167MockOs::user_cpu_time = 100;168MockOs::system_cpu_time = 100;169EXPECT_FALSE(JfrThreadCPULoadEvent::update_event(event, thread, 400 * NANOSECS_PER_MILLISEC, 2));170}171172TEST_VM_F(JfrTestThreadCPULoadSingle, UserAboveMaximum) {173174// First call will not report above 100%175MockOs::user_cpu_time = 200 * NANOSECS_PER_MILLISEC;176MockOs::system_cpu_time = 100 * NANOSECS_PER_MILLISEC;177EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, 200 * NANOSECS_PER_MILLISEC, 1));178EXPECT_FLOAT_EQ(0.5, event.user);179EXPECT_FLOAT_EQ(0.5, event.system);180181// Second call will see an extra 100 millisecs user time from the remainder182EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (200 + 400) * NANOSECS_PER_MILLISEC, 1));183EXPECT_FLOAT_EQ(0.25, event.user);184EXPECT_FLOAT_EQ(0, event.system);185186// Third call: make sure there are no leftovers187MockOs::user_cpu_time += 50 * NANOSECS_PER_MILLISEC;188MockOs::system_cpu_time += 50 * NANOSECS_PER_MILLISEC;189EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (200 + 400 + 400) * NANOSECS_PER_MILLISEC, 1));190EXPECT_FLOAT_EQ(0.125, event.user);191EXPECT_FLOAT_EQ(0.125, event.system);192}193194TEST_VM_F(JfrTestThreadCPULoadSingle, UserAboveMaximumNonZeroBase) {195196// Setup a non zero base197// Previously there was a bug when cur_user_time would be reset to zero and test that uses zero base would fail to detect it198MockOs::user_cpu_time = 100 * NANOSECS_PER_MILLISEC;199MockOs::system_cpu_time = 100 * NANOSECS_PER_MILLISEC;200EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, 400 * NANOSECS_PER_MILLISEC, 1));201EXPECT_FLOAT_EQ(0.25, event.user);202EXPECT_FLOAT_EQ(0.25, event.system);203204// First call will not report above 100%205MockOs::user_cpu_time += 200 * NANOSECS_PER_MILLISEC;206MockOs::system_cpu_time += 100 * NANOSECS_PER_MILLISEC;207EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 200) * NANOSECS_PER_MILLISEC, 1));208EXPECT_FLOAT_EQ(0.5, event.user);209EXPECT_FLOAT_EQ(0.5, event.system);210211// Second call will see an extra 100 millisecs user time from the remainder212EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 200 + 400) * NANOSECS_PER_MILLISEC, 1));213EXPECT_FLOAT_EQ(0.25, event.user);214EXPECT_FLOAT_EQ(0, event.system);215216// Third call: make sure there are no leftovers217MockOs::user_cpu_time += 50 * NANOSECS_PER_MILLISEC;218MockOs::system_cpu_time += 50 * NANOSECS_PER_MILLISEC;219EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 200 + 400 + 400) * NANOSECS_PER_MILLISEC, 1));220EXPECT_FLOAT_EQ(0.125, event.user);221EXPECT_FLOAT_EQ(0.125, event.system);222}223224TEST_VM_F(JfrTestThreadCPULoadSingle, SystemAboveMaximum) {225226// First call will not report above 100%227MockOs::user_cpu_time = 100 * NANOSECS_PER_MILLISEC;228MockOs::system_cpu_time = 300 * NANOSECS_PER_MILLISEC;229EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, 200 * NANOSECS_PER_MILLISEC, 1));230EXPECT_FLOAT_EQ(0, event.user);231EXPECT_FLOAT_EQ(1, event.system);232233// Second call will see an extra 100 millisecs user and system time from the remainder234EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (200 + 400) * NANOSECS_PER_MILLISEC, 1));235EXPECT_FLOAT_EQ(0.25, event.user);236EXPECT_FLOAT_EQ(0.25, event.system);237238// Third call: make sure there are no leftovers239MockOs::user_cpu_time += 50 * NANOSECS_PER_MILLISEC;240MockOs::system_cpu_time += 50 * NANOSECS_PER_MILLISEC;241EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (200 + 400 + 400) * NANOSECS_PER_MILLISEC, 1));242EXPECT_FLOAT_EQ(0.125, event.user);243EXPECT_FLOAT_EQ(0.125, event.system);244}245246TEST_VM_F(JfrTestThreadCPULoadSingle, SystemAboveMaximumNonZeroBase) {247248// Setup a non zero base249// Previously there was a bug when cur_user_time would be reset to zero and test that uses zero base would fail to detect it250MockOs::user_cpu_time = 100 * NANOSECS_PER_MILLISEC;251MockOs::system_cpu_time = 100 * NANOSECS_PER_MILLISEC;252EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, 400 * NANOSECS_PER_MILLISEC, 1));253EXPECT_FLOAT_EQ(0.25, event.user);254EXPECT_FLOAT_EQ(0.25, event.system);255256// First call will not report above 100%257MockOs::user_cpu_time += 100 * NANOSECS_PER_MILLISEC;258MockOs::system_cpu_time += 300 * NANOSECS_PER_MILLISEC;259EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 200) * NANOSECS_PER_MILLISEC, 1));260EXPECT_FLOAT_EQ(0, event.user);261EXPECT_FLOAT_EQ(1, event.system);262263// Second call will see an extra 100 millisecs user and system time from the remainder264EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 200 + 400) * NANOSECS_PER_MILLISEC, 1));265EXPECT_FLOAT_EQ(0.25, event.user);266EXPECT_FLOAT_EQ(0.25, event.system);267268// Third call: make sure there are no leftovers269MockOs::user_cpu_time += 50 * NANOSECS_PER_MILLISEC;270MockOs::system_cpu_time += 50 * NANOSECS_PER_MILLISEC;271EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 200 + 400 + 400) * NANOSECS_PER_MILLISEC, 1));272EXPECT_FLOAT_EQ(0.125, event.user);273EXPECT_FLOAT_EQ(0.125, event.system);274}275276TEST_VM_F(JfrTestThreadCPULoadSingle, SystemTimeDecreasing) {277278// As seen in an actual run - caused by different resolution for total and user time279// Total time User time (Calculated system time)280// 200 100 100281// 210 200 10282// 400 300 100283284MockOs::user_cpu_time = 100 * NANOSECS_PER_MILLISEC;285MockOs::system_cpu_time = 100 * NANOSECS_PER_MILLISEC;286EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, 400 * NANOSECS_PER_MILLISEC, 1));287EXPECT_FLOAT_EQ(0.25, event.user);288EXPECT_FLOAT_EQ(0.25, event.system);289290MockOs::user_cpu_time += 100 * NANOSECS_PER_MILLISEC;291MockOs::system_cpu_time -= 90 * NANOSECS_PER_MILLISEC;292EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 400) * NANOSECS_PER_MILLISEC, 1));293EXPECT_FLOAT_EQ(0.25, event.user);294EXPECT_FLOAT_EQ(0, event.system);295296MockOs::user_cpu_time += 100 * NANOSECS_PER_MILLISEC;297MockOs::system_cpu_time += 90 * NANOSECS_PER_MILLISEC;298EXPECT_TRUE(JfrThreadCPULoadEvent::update_event(event, thread, (400 + 400 + 400) * NANOSECS_PER_MILLISEC, 1));299EXPECT_FLOAT_EQ(0.25, event.user);300EXPECT_FLOAT_EQ(0, event.system);301}302303304