xref: /aosp_15_r20/art/runtime/base/timing_logger_test.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2012 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #include "timing_logger.h"
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include "base/common_art_test.h"
20*795d594fSAndroid Build Coastguard Worker 
21*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
22*795d594fSAndroid Build Coastguard Worker 
23*795d594fSAndroid Build Coastguard Worker class TimingLoggerTest : public CommonArtTest {};
24*795d594fSAndroid Build Coastguard Worker 
25*795d594fSAndroid Build Coastguard Worker // TODO: Negative test cases (improper pairing of EndSplit, etc.)
26*795d594fSAndroid Build Coastguard Worker 
TEST_F(TimingLoggerTest,StartEnd)27*795d594fSAndroid Build Coastguard Worker TEST_F(TimingLoggerTest, StartEnd) {
28*795d594fSAndroid Build Coastguard Worker   const char* split1name = "First Split";
29*795d594fSAndroid Build Coastguard Worker   TimingLogger logger("StartEnd", true, false);
30*795d594fSAndroid Build Coastguard Worker   logger.StartTiming(split1name);
31*795d594fSAndroid Build Coastguard Worker   logger.EndTiming();  // Ends split1.
32*795d594fSAndroid Build Coastguard Worker   const auto& timings = logger.GetTimings();
33*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(2U, timings.size());  // Start, End splits
34*795d594fSAndroid Build Coastguard Worker   EXPECT_TRUE(timings[0].IsStartTiming());
35*795d594fSAndroid Build Coastguard Worker   EXPECT_STREQ(timings[0].GetName(), split1name);
36*795d594fSAndroid Build Coastguard Worker   EXPECT_TRUE(timings[1].IsEndTiming());
37*795d594fSAndroid Build Coastguard Worker }
38*795d594fSAndroid Build Coastguard Worker 
39*795d594fSAndroid Build Coastguard Worker 
TEST_F(TimingLoggerTest,StartNewEnd)40*795d594fSAndroid Build Coastguard Worker TEST_F(TimingLoggerTest, StartNewEnd) {
41*795d594fSAndroid Build Coastguard Worker   const char* split1name = "First Split";
42*795d594fSAndroid Build Coastguard Worker   const char* split2name = "Second Split";
43*795d594fSAndroid Build Coastguard Worker   const char* split3name = "Third Split";
44*795d594fSAndroid Build Coastguard Worker   TimingLogger logger("StartNewEnd", true, false);
45*795d594fSAndroid Build Coastguard Worker   logger.StartTiming(split1name);
46*795d594fSAndroid Build Coastguard Worker   logger.NewTiming(split2name);
47*795d594fSAndroid Build Coastguard Worker   logger.NewTiming(split3name);
48*795d594fSAndroid Build Coastguard Worker   logger.EndTiming();
49*795d594fSAndroid Build Coastguard Worker   // Get the timings and verify that they are appropriate.
50*795d594fSAndroid Build Coastguard Worker   const auto& timings = logger.GetTimings();
51*795d594fSAndroid Build Coastguard Worker   // 6 timings in the timing logger at this point.
52*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(6U, timings.size());
53*795d594fSAndroid Build Coastguard Worker   EXPECT_TRUE(timings[0].IsStartTiming());
54*795d594fSAndroid Build Coastguard Worker   EXPECT_STREQ(timings[0].GetName(), split1name);
55*795d594fSAndroid Build Coastguard Worker   EXPECT_TRUE(timings[1].IsEndTiming());
56*795d594fSAndroid Build Coastguard Worker   EXPECT_TRUE(timings[2].IsStartTiming());
57*795d594fSAndroid Build Coastguard Worker   EXPECT_STREQ(timings[2].GetName(), split2name);
58*795d594fSAndroid Build Coastguard Worker   EXPECT_TRUE(timings[3].IsEndTiming());
59*795d594fSAndroid Build Coastguard Worker   EXPECT_TRUE(timings[4].IsStartTiming());
60*795d594fSAndroid Build Coastguard Worker   EXPECT_STREQ(timings[4].GetName(), split3name);
61*795d594fSAndroid Build Coastguard Worker   EXPECT_TRUE(timings[5].IsEndTiming());
62*795d594fSAndroid Build Coastguard Worker }
63*795d594fSAndroid Build Coastguard Worker 
TEST_F(TimingLoggerTest,StartNewEndNested)64*795d594fSAndroid Build Coastguard Worker TEST_F(TimingLoggerTest, StartNewEndNested) {
65*795d594fSAndroid Build Coastguard Worker   const char* name1 = "First Split";
66*795d594fSAndroid Build Coastguard Worker   const char* name2 = "Second Split";
67*795d594fSAndroid Build Coastguard Worker   const char* name3 = "Third Split";
68*795d594fSAndroid Build Coastguard Worker   const char* name4 = "Fourth Split";
69*795d594fSAndroid Build Coastguard Worker   const char* name5 = "Fifth Split";
70*795d594fSAndroid Build Coastguard Worker   TimingLogger logger("StartNewEndNested", true, false);
71*795d594fSAndroid Build Coastguard Worker   logger.StartTiming(name1);
72*795d594fSAndroid Build Coastguard Worker   logger.NewTiming(name2);  // Ends timing1.
73*795d594fSAndroid Build Coastguard Worker   logger.StartTiming(name3);
74*795d594fSAndroid Build Coastguard Worker   logger.StartTiming(name4);
75*795d594fSAndroid Build Coastguard Worker   logger.NewTiming(name5);  // Ends timing4.
76*795d594fSAndroid Build Coastguard Worker   logger.EndTiming();  // Ends timing5.
77*795d594fSAndroid Build Coastguard Worker   logger.EndTiming();  // Ends timing3.
78*795d594fSAndroid Build Coastguard Worker   logger.EndTiming();  // Ends timing2.
79*795d594fSAndroid Build Coastguard Worker   const auto& timings = logger.GetTimings();
80*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(10U, timings.size());
81*795d594fSAndroid Build Coastguard Worker   size_t idx_1 = logger.FindTimingIndex(name1, 0);
82*795d594fSAndroid Build Coastguard Worker   size_t idx_2 = logger.FindTimingIndex(name2, 0);
83*795d594fSAndroid Build Coastguard Worker   size_t idx_3 = logger.FindTimingIndex(name3, 0);
84*795d594fSAndroid Build Coastguard Worker   size_t idx_4 = logger.FindTimingIndex(name4, 0);
85*795d594fSAndroid Build Coastguard Worker   size_t idx_5 = logger.FindTimingIndex(name5, 0);
86*795d594fSAndroid Build Coastguard Worker   size_t idx_6 = logger.FindTimingIndex("Not found", 0);
87*795d594fSAndroid Build Coastguard Worker   EXPECT_NE(idx_1, TimingLogger::kIndexNotFound);
88*795d594fSAndroid Build Coastguard Worker   EXPECT_NE(idx_2, TimingLogger::kIndexNotFound);
89*795d594fSAndroid Build Coastguard Worker   EXPECT_NE(idx_3, TimingLogger::kIndexNotFound);
90*795d594fSAndroid Build Coastguard Worker   EXPECT_NE(idx_4, TimingLogger::kIndexNotFound);
91*795d594fSAndroid Build Coastguard Worker   EXPECT_NE(idx_5, TimingLogger::kIndexNotFound);
92*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(idx_6, TimingLogger::kIndexNotFound);
93*795d594fSAndroid Build Coastguard Worker   TimingLogger::TimingData data = logger.CalculateTimingData();
94*795d594fSAndroid Build Coastguard Worker   EXPECT_STREQ(timings[idx_1].GetName(), name1);
95*795d594fSAndroid Build Coastguard Worker   EXPECT_STREQ(timings[idx_2].GetName(), name2);
96*795d594fSAndroid Build Coastguard Worker   EXPECT_STREQ(timings[idx_3].GetName(), name3);
97*795d594fSAndroid Build Coastguard Worker   EXPECT_STREQ(timings[idx_4].GetName(), name4);
98*795d594fSAndroid Build Coastguard Worker   EXPECT_STREQ(timings[idx_5].GetName(), name5);
99*795d594fSAndroid Build Coastguard Worker }
100*795d594fSAndroid Build Coastguard Worker 
101*795d594fSAndroid Build Coastguard Worker 
TEST_F(TimingLoggerTest,Scoped)102*795d594fSAndroid Build Coastguard Worker TEST_F(TimingLoggerTest, Scoped) {
103*795d594fSAndroid Build Coastguard Worker   const char* outersplit = "Outer Split";
104*795d594fSAndroid Build Coastguard Worker   const char* innersplit1 = "Inner Split 1";
105*795d594fSAndroid Build Coastguard Worker   const char* innerinnersplit1 = "Inner Inner Split 1";
106*795d594fSAndroid Build Coastguard Worker   const char* innersplit2 = "Inner Split 2";
107*795d594fSAndroid Build Coastguard Worker   TimingLogger logger("Scoped", true, false);
108*795d594fSAndroid Build Coastguard Worker   {
109*795d594fSAndroid Build Coastguard Worker     TimingLogger::ScopedTiming outer(outersplit, &logger);
110*795d594fSAndroid Build Coastguard Worker     {
111*795d594fSAndroid Build Coastguard Worker       TimingLogger::ScopedTiming inner1(innersplit1, &logger);
112*795d594fSAndroid Build Coastguard Worker       {
113*795d594fSAndroid Build Coastguard Worker         TimingLogger::ScopedTiming innerinner1(innerinnersplit1, &logger);
114*795d594fSAndroid Build Coastguard Worker       }  // Ends innerinnersplit1.
115*795d594fSAndroid Build Coastguard Worker     }  // Ends innersplit1.
116*795d594fSAndroid Build Coastguard Worker     {
117*795d594fSAndroid Build Coastguard Worker       TimingLogger::ScopedTiming inner2(innersplit2, &logger);
118*795d594fSAndroid Build Coastguard Worker     }  // Ends innersplit2.
119*795d594fSAndroid Build Coastguard Worker   }  // Ends outersplit.
120*795d594fSAndroid Build Coastguard Worker   const size_t idx_outersplit = logger.FindTimingIndex(outersplit, 0);
121*795d594fSAndroid Build Coastguard Worker   const size_t idx_innersplit1 = logger.FindTimingIndex(innersplit1, 0);
122*795d594fSAndroid Build Coastguard Worker   const size_t idx_innerinnersplit1 = logger.FindTimingIndex(innerinnersplit1, 0);
123*795d594fSAndroid Build Coastguard Worker   const size_t idx_innersplit2 = logger.FindTimingIndex(innersplit2, 0);
124*795d594fSAndroid Build Coastguard Worker   const auto& timings = logger.GetTimings();
125*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(8U, timings.size());  // 4 start timings and 4 end timings.
126*795d594fSAndroid Build Coastguard Worker   EXPECT_GE(timings[idx_innerinnersplit1].GetTime(), timings[idx_innersplit1].GetTime());
127*795d594fSAndroid Build Coastguard Worker   EXPECT_GE(timings[idx_innersplit2].GetTime(), timings[idx_innersplit1].GetTime());
128*795d594fSAndroid Build Coastguard Worker   TimingLogger::TimingData data(logger.CalculateTimingData());
129*795d594fSAndroid Build Coastguard Worker   EXPECT_GE(data.GetTotalTime(idx_outersplit), data.GetTotalTime(idx_innerinnersplit1));
130*795d594fSAndroid Build Coastguard Worker   EXPECT_GE(data.GetTotalTime(idx_outersplit),
131*795d594fSAndroid Build Coastguard Worker             data.GetTotalTime(idx_innersplit1) + data.GetTotalTime(idx_innersplit2));
132*795d594fSAndroid Build Coastguard Worker   EXPECT_GE(data.GetTotalTime(idx_innersplit1), data.GetTotalTime(idx_innerinnersplit1));
133*795d594fSAndroid Build Coastguard Worker }
134*795d594fSAndroid Build Coastguard Worker 
135*795d594fSAndroid Build Coastguard Worker 
TEST_F(TimingLoggerTest,ScopedAndExplicit)136*795d594fSAndroid Build Coastguard Worker TEST_F(TimingLoggerTest, ScopedAndExplicit) {
137*795d594fSAndroid Build Coastguard Worker   const char* outersplit = "Outer Split";
138*795d594fSAndroid Build Coastguard Worker   const char* innersplit = "Inner Split";
139*795d594fSAndroid Build Coastguard Worker   const char* innerinnersplit1 = "Inner Inner Split 1";
140*795d594fSAndroid Build Coastguard Worker   const char* innerinnersplit2 = "Inner Inner Split 2";
141*795d594fSAndroid Build Coastguard Worker   TimingLogger logger("Scoped", true, false);
142*795d594fSAndroid Build Coastguard Worker   logger.StartTiming(outersplit);
143*795d594fSAndroid Build Coastguard Worker   {
144*795d594fSAndroid Build Coastguard Worker     TimingLogger::ScopedTiming inner(innersplit, &logger);
145*795d594fSAndroid Build Coastguard Worker     logger.StartTiming(innerinnersplit1);
146*795d594fSAndroid Build Coastguard Worker     logger.NewTiming(innerinnersplit2);  // Ends innerinnersplit1.
147*795d594fSAndroid Build Coastguard Worker     logger.EndTiming();
148*795d594fSAndroid Build Coastguard Worker   }  // Ends innerinnersplit2, then innersplit.
149*795d594fSAndroid Build Coastguard Worker   logger.EndTiming();  // Ends outersplit.
150*795d594fSAndroid Build Coastguard Worker   const size_t idx_outersplit = logger.FindTimingIndex(outersplit, 0);
151*795d594fSAndroid Build Coastguard Worker   const size_t idx_innersplit = logger.FindTimingIndex(innersplit, 0);
152*795d594fSAndroid Build Coastguard Worker   const size_t idx_innerinnersplit1 = logger.FindTimingIndex(innerinnersplit1, 0);
153*795d594fSAndroid Build Coastguard Worker   const size_t idx_innerinnersplit2 = logger.FindTimingIndex(innerinnersplit2, 0);
154*795d594fSAndroid Build Coastguard Worker   const auto& timings = logger.GetTimings();
155*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(8U, timings.size());
156*795d594fSAndroid Build Coastguard Worker   EXPECT_LE(timings[idx_outersplit].GetTime(), timings[idx_innersplit].GetTime());
157*795d594fSAndroid Build Coastguard Worker   EXPECT_LE(timings[idx_innersplit].GetTime(), timings[idx_innerinnersplit1].GetTime());
158*795d594fSAndroid Build Coastguard Worker   EXPECT_LE(timings[idx_innerinnersplit1].GetTime(), timings[idx_innerinnersplit2].GetTime());
159*795d594fSAndroid Build Coastguard Worker }
160*795d594fSAndroid Build Coastguard Worker 
TEST_F(TimingLoggerTest,ThreadCpuAndMonotonic)161*795d594fSAndroid Build Coastguard Worker TEST_F(TimingLoggerTest, ThreadCpuAndMonotonic) {
162*795d594fSAndroid Build Coastguard Worker   TimingLogger mon_logger("Scoped", true, false, TimingLogger::TimingKind::kMonotonic);
163*795d594fSAndroid Build Coastguard Worker   TimingLogger cpu_logger("Scoped", true, false, TimingLogger::TimingKind::kThreadCpu);
164*795d594fSAndroid Build Coastguard Worker   mon_logger.StartTiming("MON");
165*795d594fSAndroid Build Coastguard Worker   cpu_logger.StartTiming("CPU");
166*795d594fSAndroid Build Coastguard Worker 
167*795d594fSAndroid Build Coastguard Worker   sleep(2);
168*795d594fSAndroid Build Coastguard Worker 
169*795d594fSAndroid Build Coastguard Worker   cpu_logger.EndTiming();
170*795d594fSAndroid Build Coastguard Worker   mon_logger.EndTiming();
171*795d594fSAndroid Build Coastguard Worker   uint64_t mon_timing = mon_logger.GetTimings()[1].GetTime() - mon_logger.GetTimings()[0].GetTime();
172*795d594fSAndroid Build Coastguard Worker   uint64_t cpu_timing = cpu_logger.GetTimings()[1].GetTime() - cpu_logger.GetTimings()[0].GetTime();
173*795d594fSAndroid Build Coastguard Worker   EXPECT_LT(cpu_timing, MsToNs(1000u));
174*795d594fSAndroid Build Coastguard Worker   EXPECT_GT(mon_timing, MsToNs(1000u));
175*795d594fSAndroid Build Coastguard Worker   EXPECT_LT(cpu_timing, mon_timing);
176*795d594fSAndroid Build Coastguard Worker }
177*795d594fSAndroid Build Coastguard Worker 
178*795d594fSAndroid Build Coastguard Worker }  // namespace art
179