// Copyright 2026 Dolphin Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "Common/PerformanceTrace.h" #include using namespace Common::PerformanceTrace; TEST(PerformanceTrace, NestedTimesAreExclusive) { ScopeStack stack; ASSERT_TRUE(stack.Begin(Region::Slice, 100)); ASSERT_TRUE(stack.Begin(Region::ARM, 110)); ASSERT_TRUE(stack.Begin(Region::Journal, 120)); ASSERT_TRUE(stack.End(150)); ASSERT_TRUE(stack.End(180)); ASSERT_TRUE(stack.End(200)); const auto& t = stack.Timings(); EXPECT_EQ(t[static_cast(Region::Slice)].inclusive, 100u); EXPECT_EQ(t[static_cast(Region::Slice)].exclusive, 30u); EXPECT_EQ(t[static_cast(Region::ARM)].exclusive, 40u); EXPECT_EQ(t[static_cast(Region::Journal)].exclusive, 30u); EXPECT_EQ(stack.Errors(), 0u); EXPECT_EQ(stack.Depth(), 0u); } TEST(PerformanceTrace, RecursiveRegionAndReset) { ScopeStack stack; ASSERT_TRUE(stack.Begin(Region::ARM, 0)); ASSERT_TRUE(stack.Begin(Region::ARM, 10)); ASSERT_TRUE(stack.End(20)); ASSERT_TRUE(stack.End(30)); EXPECT_EQ(stack.Timings()[static_cast(Region::ARM)].exclusive, 30u); EXPECT_EQ(stack.Timings()[static_cast(Region::ARM)].calls, 2u); stack.Reset(); EXPECT_EQ(stack.Timings()[static_cast(Region::ARM)].calls, 0u); EXPECT_EQ(stack.Depth(), 0u); } TEST(PerformanceTrace, InvalidClockAndUnderflowAreReported) { ScopeStack stack; EXPECT_FALSE(stack.End(0)); ASSERT_TRUE(stack.Begin(Region::ARM, 100)); EXPECT_FALSE(stack.End(99)); EXPECT_EQ(stack.Errors(), 2u); EXPECT_EQ(stack.Timings()[static_cast(Region::ARM)].inclusive, 0u); } TEST(PerformanceTrace, DepthOverflowIsBounded) { ScopeStack stack; for (u64 i = 0; i < 32; ++i) ASSERT_TRUE(stack.Begin(Region::ARM, i)); EXPECT_FALSE(stack.Begin(Region::ARM, 32)); for (u64 i = 0; i < 32; ++i) ASSERT_TRUE(stack.End(40 + i)); EXPECT_EQ(stack.Depth(), 0u); EXPECT_EQ(stack.Errors(), 1u); }