• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <gmock/gmock.h>
18 #include <gtest/gtest.h>
19 
20 #include "aidl/UClampVoter.h"
21 
22 namespace aidl {
23 namespace google {
24 namespace hardware {
25 namespace power {
26 namespace impl {
27 namespace pixel {
28 
29 using std::literals::chrono_literals::operator""s;
30 using std::literals::chrono_literals::operator""ms;
31 using std::literals::chrono_literals::operator""ns;
32 
33 using testing::Optional;
34 
TEST(VoteRange,active)35 TEST(VoteRange, active) {
36     auto tNow = std::chrono::steady_clock::now();
37     VoteRange vr(true, tNow, 200ms);
38     EXPECT_TRUE(vr.active());
39 }
40 
TEST(VoteRange,inActive)41 TEST(VoteRange, inActive) {
42     auto tNow = std::chrono::steady_clock::now();
43     VoteRange vr(false, tNow, 200ms);
44     EXPECT_FALSE(vr.active());
45 }
46 
TEST(VoteRange,defaultConstructorValues)47 TEST(VoteRange, defaultConstructorValues) {
48     UclampRange uclamp_range;
49     EXPECT_EQ(0, uclamp_range.uclampMin);
50     EXPECT_EQ(1024, uclamp_range.uclampMax);
51 }
52 
TEST(VoteRange,isTimeInRange)53 TEST(VoteRange, isTimeInRange) {
54     const auto tNow = std::chrono::steady_clock::now();
55     VoteRange vote_range(true, tNow, 250ms);
56     EXPECT_FALSE(vote_range.isTimeInRange(tNow - 1ns));
57     EXPECT_TRUE(vote_range.isTimeInRange(tNow));
58     EXPECT_TRUE(vote_range.isTimeInRange(tNow + 1ns));
59     EXPECT_TRUE(vote_range.isTimeInRange(tNow + 250ms));
60     EXPECT_FALSE(vote_range.isTimeInRange(tNow + 250ms + 1ns));
61 }
62 
TEST(VoteRange,isTimeInRangeInActive)63 TEST(VoteRange, isTimeInRangeInActive) {
64     const auto tNow = std::chrono::steady_clock::now();
65     VoteRange vote_range(true, tNow, 250ms);
66     EXPECT_TRUE(vote_range.active());
67     vote_range.setActive(false);
68     EXPECT_FALSE(vote_range.active());
69     EXPECT_FALSE(vote_range.isTimeInRange(tNow));
70     EXPECT_FALSE(vote_range.isTimeInRange(tNow + 1ns));
71     EXPECT_FALSE(vote_range.isTimeInRange(tNow + 250ms));
72     EXPECT_FALSE(vote_range.isTimeInRange(tNow + 250ms + 1ns));
73 }
74 
TEST(VoteRange,getUclampRange)75 TEST(VoteRange, getUclampRange) {
76     const auto tNow = std::chrono::steady_clock::now();
77     const auto tNext = tNow + 1s;
78     const auto tEnd1 = tNow + 4000000001ns;
79     const auto tPrev = tNow - 1s;
80 
81     VoteRange voteFirst(true, tNow, 4000000000ns);
82     EXPECT_FALSE(voteFirst.isTimeInRange(tPrev));
83     EXPECT_TRUE(voteFirst.isTimeInRange(tNext));
84     EXPECT_FALSE(voteFirst.isTimeInRange(tEnd1));
85 
86     Votes votes;
87     votes.add(1,
88               CpuVote(voteFirst.active(), voteFirst.startTime(), voteFirst.durationNs(), 11, 1024));
89     UclampRange ur;
90 
91     votes.getUclampRange(ur, tNext);
92     EXPECT_EQ(11, ur.uclampMin);
93     EXPECT_EQ(kUclampMax, ur.uclampMax);
94 }
95 
TEST(UclampVoter,simple)96 TEST(UclampVoter, simple) {
97     const auto tNow = std::chrono::steady_clock::now();
98 
99     auto votes = std::make_shared<Votes>();
100     EXPECT_EQ(0, votes->size());
101 
102     votes->add(1, CpuVote(true, tNow, 4s, 11, 1024));
103     EXPECT_EQ(1, votes->size());
104 
105     votes->add(2, CpuVote(true, tNow, 1s, 22, 1024));
106     EXPECT_EQ(2, votes->size());
107 
108     UclampRange ur1;
109     votes->getUclampRange(ur1, tNow);
110     EXPECT_EQ(22, ur1.uclampMin);
111     EXPECT_EQ(kUclampMax, ur1.uclampMax);
112 
113     UclampRange ur2;
114     votes->getUclampRange(ur2, tNow + 2s);
115     EXPECT_EQ(11, ur2.uclampMin);
116     EXPECT_EQ(kUclampMax, ur2.uclampMax);
117 
118     UclampRange ur3;
119     votes->getUclampRange(ur3, tNow + 5s);
120     EXPECT_EQ(0, ur3.uclampMin);
121     EXPECT_EQ(1024, ur3.uclampMax);
122 
123     EXPECT_FALSE(votes->allTimedOut(tNow + 200ns));
124     EXPECT_TRUE(votes->allTimedOut(tNow + 5s));
125 
126     EXPECT_TRUE(votes->setUseVote(2, false));
127     EXPECT_TRUE(votes->anyTimedOut(tNow + 5s));
128     EXPECT_TRUE(votes->setUseVote(2, true));
129 
130     EXPECT_FALSE(votes->anyTimedOut(tNow + 200ns));
131 }
132 
TEST(UclampVoter,overwrite)133 TEST(UclampVoter, overwrite) {
134     const auto tNow = std::chrono::steady_clock::now();
135 
136     auto votes = std::make_shared<Votes>();
137     EXPECT_EQ(0, votes->size());
138 
139     votes->add(1, CpuVote(true, tNow, 4s, 11, 1024));
140     EXPECT_EQ(1, votes->size());
141 
142     votes->add(2, CpuVote(true, tNow, 2s, 22, 1024));
143     EXPECT_EQ(2, votes->size());
144 
145     UclampRange ucr1;
146     votes->getUclampRange(ucr1, tNow + 1s);
147     EXPECT_EQ(22, ucr1.uclampMin);
148 
149     votes->add(1, CpuVote(true, tNow, 5s, 32, 1024));
150     UclampRange ucr2;
151     votes->getUclampRange(ucr2, tNow + 1s);
152     EXPECT_EQ(32, ucr2.uclampMin);
153 }
154 
TEST(UclampVoter,updateDuration)155 TEST(UclampVoter, updateDuration) {
156     const auto tNow = std::chrono::steady_clock::now();
157 
158     auto votes = std::make_shared<Votes>();
159     EXPECT_EQ(0, votes->size());
160 
161     votes->add(1, CpuVote(true, tNow, 4s, 11, 1024));
162     votes->add(2, CpuVote(true, tNow, 2s, 22, 1024));
163     EXPECT_EQ(2, votes->size());
164 
165     EXPECT_TRUE(votes->allTimedOut(tNow + 7s));
166     votes->updateDuration(1, 8s);
167     EXPECT_FALSE(votes->allTimedOut(tNow + 7s));
168     votes->updateDuration(5, 10s);
169     EXPECT_TRUE(votes->allTimedOut(tNow + 9s));
170 }
171 
TEST(UclampVoter,loadVoteTest)172 TEST(UclampVoter, loadVoteTest) {
173     const int defaultVoteId = 1;
174     const int loadVoteId = 2;
175     const int uclampMinDefault = 50;
176     const int uclampMinInit = 162;
177     const int uclampMinHigh = 450;
178     const auto tNow = std::chrono::steady_clock::now();
179     UclampRange ucr;
180     auto votes = std::make_shared<Votes>();
181 
182     // Default: min = 50 (original)
183     votes->add(defaultVoteId, CpuVote(true, tNow, 400ms, uclampMinDefault, 1024));
184     votes->getUclampRange(ucr, tNow + 100ms);
185     EXPECT_EQ(uclampMinDefault, ucr.uclampMin);
186 
187     // Default: min = UclampMinInit
188     votes->add(defaultVoteId, CpuVote(true, tNow, 400ns, uclampMinInit, 1024));
189     // Load: min = uclampMinHigh
190     votes->add(loadVoteId, CpuVote(true, tNow, 250ns, uclampMinHigh, 1024));
191 
192     // Check that load is enabled
193     ucr.uclampMin = 0;
194     votes->getUclampRange(ucr, tNow + 100ns);
195     EXPECT_EQ(uclampMinHigh, ucr.uclampMin);
196 
197     // Timeout or restore after 1st frame
198     // Expect to get 162.
199     ucr.uclampMin = 0;
200     votes->getUclampRange(ucr, tNow + 350ns);
201     EXPECT_EQ(uclampMinInit, ucr.uclampMin);
202 }
203 
TEST(GpuCapacityVoter,testIncorrectTyping)204 TEST(GpuCapacityVoter, testIncorrectTyping) {
205     const auto now = std::chrono::steady_clock::now();
206     Votes votes;
207     static constexpr int gpu_vote_id = static_cast<int>(AdpfVoteType::GPU_CAPACITY);
208     static constexpr int cpu_vote_id = static_cast<int>(AdpfVoteType::CPU_LOAD_UP);
209 
210     votes.add(cpu_vote_id, GpuVote(true, now, 250ns, Cycles(1024)));
211     EXPECT_FALSE(votes.voteIsActive(cpu_vote_id));
212     EXPECT_FALSE(votes.setUseVote(cpu_vote_id, true));
213     EXPECT_FALSE(votes.remove(cpu_vote_id));
214 
215     votes.add(gpu_vote_id, CpuVote(true, now, 250ns, 66, 77));
216     EXPECT_FALSE(votes.voteIsActive(gpu_vote_id));
217     EXPECT_FALSE(votes.setUseVote(cpu_vote_id, true));
218     EXPECT_FALSE(votes.remove(cpu_vote_id));
219 
220     UclampRange range;
221     votes.getUclampRange(range, now);
222     EXPECT_EQ(range.uclampMin, 0);
223     EXPECT_EQ(range.uclampMax, 1024);
224 
225     EXPECT_FALSE(votes.getGpuCapacityRequest(now));
226 }
227 
TEST(GpuCapacityVoter,testGpuUseVote)228 TEST(GpuCapacityVoter, testGpuUseVote) {
229     const auto now = std::chrono::steady_clock::now();
230     Votes votes;
231     static constexpr int gpu_vote_id1 = static_cast<int>(AdpfVoteType::GPU_CAPACITY);
232     static constexpr int gpu_vote_id2 = static_cast<int>(AdpfVoteType::GPU_LOAD_UP);
233 
234     votes.add(gpu_vote_id1, GpuVote(true, now, 250ns, Cycles(1024)));
235     EXPECT_TRUE(votes.setUseVote(gpu_vote_id1, true));
236     EXPECT_FALSE(votes.setUseVote(gpu_vote_id2, true));
237 }
238 
TEST(GpuCapacityVoter,testBasicVoteActivation)239 TEST(GpuCapacityVoter, testBasicVoteActivation) {
240     auto const now = std::chrono::steady_clock::now();
241     auto const timeout = 1s;
242     auto const gpu_vote_id = static_cast<int>(AdpfVoteType::GPU_CAPACITY);
243     Votes votes;
244 
245     votes.add(gpu_vote_id, GpuVote(true, now, 250ns, Cycles(100)));
246 
247     EXPECT_EQ(votes.size(), 1);
248     EXPECT_TRUE(votes.voteIsActive(gpu_vote_id));
249 
250     votes.setUseVote(gpu_vote_id, false);
251     EXPECT_FALSE(votes.voteIsActive(gpu_vote_id));
252 
253     votes.setUseVote(gpu_vote_id, true);
254     EXPECT_TRUE(votes.voteIsActive(gpu_vote_id));
255 
256     EXPECT_TRUE(votes.remove(gpu_vote_id));
257 }
258 
TEST(GpuCapacityVoter,testBasicVoteTimeouts)259 TEST(GpuCapacityVoter, testBasicVoteTimeouts) {
260     auto const now = std::chrono::steady_clock::now();
261     auto const timeout = 1s;
262     auto const gpu_vote_id = static_cast<int>(AdpfVoteType::GPU_CAPACITY);
263     Cycles const cycles(100);
264 
265     Votes votes;
266     votes.add(gpu_vote_id, GpuVote(true, now, timeout, cycles));
267 
268     EXPECT_THAT(votes.getGpuCapacityRequest(now + 1ns), Optional(Cycles(100)));
269 
270     auto capacity2 = votes.getGpuCapacityRequest(now + 2 * timeout);
271     EXPECT_FALSE(capacity2);
272 }
273 
TEST(GpuCapacityVoter,testVoteTimeouts)274 TEST(GpuCapacityVoter, testVoteTimeouts) {
275     auto const now = std::chrono::steady_clock::now();
276     auto const timeout = 1s;
277     auto const timeout2 = 10s;
278     auto const gpu_vote_id = static_cast<int>(AdpfVoteType::GPU_CAPACITY);
279     auto const cpu_vote_id = static_cast<int>(AdpfVoteType::CPU_LOAD_UP);
280     Cycles const cycles(100);
281 
282     Votes votes;
283     votes.add(gpu_vote_id, GpuVote(true, now, timeout, cycles));
284     votes.add(cpu_vote_id, CpuVote(true, now, timeout2, 66, 88));
285 
286     EXPECT_EQ(votes.size(), 2);
287     EXPECT_EQ(votes.voteTimeout(gpu_vote_id), now + timeout);
288 
289     EXPECT_FALSE(votes.allTimedOut(now + std::chrono::microseconds(56)));
290     EXPECT_FALSE(votes.anyTimedOut(now + std::chrono::microseconds(56)));
291     EXPECT_FALSE(votes.allTimedOut(now + 2 * timeout));
292     EXPECT_TRUE(votes.anyTimedOut(now + 2 * timeout));
293     EXPECT_TRUE(votes.allTimedOut(now + 20 * timeout));
294     EXPECT_TRUE(votes.anyTimedOut(now + 20 * timeout));
295 }
296 
TEST(GpuCapacityVoter,testGpuVoteActive)297 TEST(GpuCapacityVoter, testGpuVoteActive) {
298     auto const now = std::chrono::steady_clock::now();
299     auto const timeout = 1s;
300     auto const gpu_vote_id = static_cast<int>(AdpfVoteType::GPU_CAPACITY);
301     Cycles const cycles(100);
302 
303     Votes votes;
304     votes.add(gpu_vote_id, GpuVote(true, now, timeout, cycles));
305 
306     EXPECT_TRUE(votes.voteIsActive(gpu_vote_id));
307     EXPECT_THAT(votes.getGpuCapacityRequest(now), Optional(cycles));
308     EXPECT_TRUE(votes.setUseVote(gpu_vote_id, false));
309     ASSERT_FALSE(votes.getGpuCapacityRequest(now));
310 
311     EXPECT_FALSE(votes.voteIsActive(gpu_vote_id));
312 
313     EXPECT_EQ(votes.size(), 1);
314 }
315 
TEST(GpuCapacityVoter,testGpuVoteSum)316 TEST(GpuCapacityVoter, testGpuVoteSum) {
317     auto const now = std::chrono::steady_clock::now();
318 
319     auto const capacity_vote_id = static_cast<int>(AdpfVoteType::GPU_CAPACITY);
320     auto const load_vote_id = static_cast<int>(AdpfVoteType::GPU_LOAD_UP);
321 
322     Votes votes;
323     votes.add(capacity_vote_id, GpuVote(true, now, 100ms, Cycles(321)));
324     votes.add(load_vote_id, GpuVote(true, now, 50ms, Cycles(123)));
325 
326     EXPECT_TRUE(votes.voteIsActive(capacity_vote_id));
327     EXPECT_TRUE(votes.voteIsActive(load_vote_id));
328 
329     EXPECT_THAT(votes.getGpuCapacityRequest(now + 1ms), Optional(Cycles(444)));
330     EXPECT_THAT(votes.getGpuCapacityRequest(now + 51ms), Optional(Cycles(321)));
331     EXPECT_FALSE(votes.getGpuCapacityRequest(now + 101ms));
332 
333     EXPECT_TRUE(votes.setUseVote(load_vote_id, false));
334     EXPECT_TRUE(votes.voteIsActive(capacity_vote_id));
335     EXPECT_FALSE(votes.voteIsActive(load_vote_id));
336     EXPECT_THAT(votes.getGpuCapacityRequest(now + 1ms), Optional(Cycles(321)));
337 
338     EXPECT_EQ(votes.size(), 2);
339 }
340 }  // namespace pixel
341 }  // namespace impl
342 }  // namespace power
343 }  // namespace hardware
344 }  // namespace google
345 }  // namespace aidl
346