• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <benchmark/benchmark.h>
17 #include "timer.h"
18 #include "common_timer_errors.h"
19 #include <iostream>
20 #include <thread>
21 #include <chrono>
22 #include <stdatomic.h>
23 #include <sys/time.h>
24 #include "../log.h"
25 #include "../assert.h"
26 using namespace std;
27 
28 namespace OHOS {
29 namespace {
30 
31 const int MICROSECONDS_IN_ONE_SECOND = 1000000;
32 const int MICROSECONDS_IN_ONE_MILLISECOND = 1000;
33 
CurMs()34 int64_t CurMs()
35 {
36     struct timeval tpend;
37     gettimeofday(&tpend, nullptr);
38     return (tpend.tv_sec * MICROSECONDS_IN_ONE_SECOND + tpend.tv_usec) / MICROSECONDS_IN_ONE_MILLISECOND;
39 }
40 
41 class BenchmarkTimerTest : public benchmark::Fixture {
42 public:
BenchmarkTimerTest()43     BenchmarkTimerTest()
44     {
45         Iterations(iterations);
46         Repetitions(repetitions);
47         ReportAggregatesOnly();
48     }
49 
50     ~BenchmarkTimerTest() override = default;
SetUp(const::benchmark::State & state)51     void SetUp(const ::benchmark::State& state) override
52     {
53     }
54 
TearDown(const::benchmark::State & state)55     void TearDown(const ::benchmark::State& state) override
56     {
57     }
58 
59 protected:
60     const int32_t repetitions = 3;
61     const int32_t iterations = 50;
62 };
63 
64 std::atomic<int> g_data1(0);
TimeOutCallback1()65 void TimeOutCallback1()
66 {
67     g_data1 += 1;
68 }
69 
70 std::atomic<int> g_data2(0);
TimeOutCallback2()71 void TimeOutCallback2()
72 {
73     g_data2 += 1;
74 }
75 
76 /*
77  * @tc.name: testTimer002
78  * @tc.desc: timer unit test
79  */
BENCHMARK_F(BenchmarkTimerTest,testTimer002)80 BENCHMARK_F(BenchmarkTimerTest, testTimer002)(benchmark::State& state)
81 {
82     BENCHMARK_LOGD("TimerTest testTimer002 start.");
83     while (state.KeepRunning()) {
84         BENCHMARK_LOGD("TimerTest testTimer002 in.");
85         g_data1 = 0;
86         Utils::Timer timer("test_timer");
87         uint32_t ret = timer.Setup();
88         AssertEqual(Utils::TIMER_ERR_OK, ret, "Utils::TIMER_ERR_OK did not equal ret as expected.", state);
89         timer.Register(TimeOutCallback1, 1, true);
90         std::this_thread::sleep_for(std::chrono::milliseconds(15));
91         timer.Shutdown();
92         AssertEqual(1, g_data1, "1 did not equal g_data1 as expected.", state);
93     }
94     BENCHMARK_LOGD("TimerTest testTimer002 end.");
95 }
96 
97 /*
98  * @tc.name: testTimer003
99  * @tc.desc: timer unit test
100  */
BENCHMARK_F(BenchmarkTimerTest,testTimer003)101 BENCHMARK_F(BenchmarkTimerTest, testTimer003)(benchmark::State& state)
102 {
103     BENCHMARK_LOGD("TimerTest testTimer003 start.");
104     while (state.KeepRunning()) {
105         g_data1 = 0;
106         g_data2 = 0;
107         Utils::Timer timer("test_timer");
108         uint32_t ret = timer.Setup();
109         AssertEqual(Utils::TIMER_ERR_OK, ret, "Utils::TIMER_ERR_OK did not equal ret as expected.", state);
110         timer.Register(TimeOutCallback1, 1);
111         timer.Register(TimeOutCallback2, 50);
112         std::this_thread::sleep_for(std::chrono::milliseconds(500));
113         timer.Shutdown();
114         AssertGreaterThanOrEqual(g_data1, 8, "g_data1 was not greater than or equal to 8 as expected.", state);
115         AssertGreaterThanOrEqual(g_data2, 2, "g_data2 was not greater than or equal to 2 as expected.", state);
116     }
117     BENCHMARK_LOGD("TimerTest testTimer003 end.");
118 }
119 
120 /*
121  * @tc.name: testTimer004
122  * @tc.desc: timer unit test
123  */
BENCHMARK_F(BenchmarkTimerTest,testTimer004)124 BENCHMARK_F(BenchmarkTimerTest, testTimer004)(benchmark::State& state)
125 {
126     BENCHMARK_LOGD("TimerTest testTimer004 start.");
127     while (state.KeepRunning()) {
128         g_data1 = 0;
129         Utils::Timer timer("test_timer");
130         uint32_t ret = timer.Setup();
131         AssertEqual(Utils::TIMER_ERR_OK, ret, "Utils::TIMER_ERR_OK did not equal ret as expected.", state);
132         timer.Register(TimeOutCallback1, 1);
133         timer.Register(TimeOutCallback1, 2);
134         std::this_thread::sleep_for(std::chrono::milliseconds(30));
135         timer.Shutdown();
136         AssertGreaterThanOrEqual(g_data1, 5, "g_data1 was not greater than or equal to 5 as expected.", state);
137     }
138     BENCHMARK_LOGD("TimerTest testTimer004 end.");
139 }
140 
141 class A {
142 public:
A(int data)143     explicit A(int data) : data_(data), timer_("ATimer") {}
144     ~A() = default;
145     bool Init();
146     bool StartTimer(int milliseconds, bool once);
147     void StopTimer();
GetData() const148     int GetData() const {return data_;}
149 private:
TimeOutProc()150     void TimeOutProc()
151     {
152         BENCHMARK_LOGD("TimerTest void TimeOutProc is called.");
153         data_ -= 1;
154     }
155     int data_;
156     Utils::Timer timer_;
157 };
158 
Init()159 bool A::Init()
160 {
161     BENCHMARK_LOGD("TimerTest bool A::Init is called.");
162     return timer_.Setup() == Utils::TIMER_ERR_OK;
163 }
164 
StartTimer(int milliseconds,bool once)165 bool A::StartTimer(int milliseconds, bool once)
166 {
167     BENCHMARK_LOGD("TimerTest bool A::StartTimer is called.");
168     uint32_t timerId = timer_.Register(std::bind(&A::TimeOutProc, this), milliseconds, once);
169     return timerId != Utils::TIMER_ERR_DEAL_FAILED;
170 }
171 
StopTimer()172 void A::StopTimer()
173 {
174     BENCHMARK_LOGD("TimerTest void A::StopTimer is called.");
175     timer_.Shutdown();
176 }
177 
178 /*
179  * @tc.name: testTimer006
180  * @tc.desc: timer unit test
181  */
BENCHMARK_F(BenchmarkTimerTest,testTimer006)182 BENCHMARK_F(BenchmarkTimerTest, testTimer006)(benchmark::State& state)
183 {
184     BENCHMARK_LOGD("testTimer006 start.");
185     while (state.KeepRunning()) {
186         A a(10);
187         AssertTrue(a.Init(), "a.Init() did not equal true as expected.", state);
188         AssertTrue(a.StartTimer(1, true), "a.StartTimer(1, true) did not equal true as expected.", state);
189         std::this_thread::sleep_for(std::chrono::milliseconds(20));
190         a.StopTimer();
191         AssertEqual(9, a.GetData(), "9 did not equal a.GetData() as expected.", state);
192     }
193     BENCHMARK_LOGD("testTimer006 end.");
194 }
195 
196 /*
197  * @tc.name: testTimer007
198  * @tc.desc: abnormal case
199  */
BENCHMARK_F(BenchmarkTimerTest,testTimer007)200 BENCHMARK_F(BenchmarkTimerTest, testTimer007)(benchmark::State& state)
201 {
202     BENCHMARK_LOGD("testTimer007 start.");
203     while (state.KeepRunning()) {
204         g_data1 = 0;
205         Utils::Timer timer("test_timer", -1);
206         uint32_t ret = timer.Setup();
207         AssertEqual(Utils::TIMER_ERR_OK, ret, "Utils::TIMER_ERR_OK did not equal ret as expected.", state);
208 
209         uint32_t timerId = 0;
210         for (uint32_t i = 0; i < 10; i++) {
211             timerId = timer.Register(TimeOutCallback1, 7, true);
212             std::this_thread::sleep_for(std::chrono::milliseconds(10));
213         }
214         timer.Unregister(timerId);
215         timer.Shutdown(false);
216         BENCHMARK_LOGD("testTimer007 g_data1:%{public}d", (int)g_data1);
217         AssertGreaterThanOrEqual(g_data1, 5, "g_data1 was not greater than or equal to 5 as expected.", state);
218     }
219     BENCHMARK_LOGD("testTimer007 end.");
220 }
221 
222 /*
223  * @tc.name: testTimer008
224  * @tc.desc: timer sleep test for ivi
225  */
BENCHMARK_F(BenchmarkTimerTest,testTimer008)226 BENCHMARK_F(BenchmarkTimerTest, testTimer008)(benchmark::State& state)
227 {
228     BENCHMARK_LOGD("TimerTest testTimer008 start.");
229     while (state.KeepRunning()) {
230         g_data1 = 0;
231         Utils::Timer timer("test_timer");
232         uint32_t ret = timer.Setup();
233         AssertEqual(Utils::TIMER_ERR_OK, ret, "Utils::TIMER_ERR_OK did not equal ret as expected.", state);
234         timer.Register(TimeOutCallback1, 10);
235 
236         for (int i = 0; i < 11; i++) {
237             int64_t pre = CurMs();
238             std::this_thread::sleep_for(std::chrono::milliseconds(10));
239             int64_t cur = CurMs();
240             AssertGreaterThanOrEqual(cur - pre, 10,
241                 "(cur - pre) was not greater than or equal to 10 as expected.", state);
242         }
243         timer.Shutdown();
244         AssertGreaterThanOrEqual(g_data1, 10, "g_data1 was not greater than or equal to 10 as expected.", state);
245     }
246     BENCHMARK_LOGD("TimerTest testTimer008 end.");
247 }
248 
249 const int MAX_COUNT = 9;
250 const int TIMER_DELAY = 10;
251 
252 /*
253  * @tc.name: testTimer009
254  * @tc.desc: recursive test
255  */
DoFunc(Utils::Timer & timer,int & count)256 void DoFunc(Utils::Timer &timer, int &count)
257 {
258     BENCHMARK_LOGD("TimerTest void DoFunc is called.");
259     (void)timer.Register(
260         [&timer, &count]() {
261             count += 1;
262             if (count > MAX_COUNT) {
263                 return;
264             }
265             DoFunc(timer, count);
266         },
267         TIMER_DELAY,
268         true);
269     g_data1++;
270 }
271 
DoFunc2(Utils::Timer & timer,int & count)272 void DoFunc2(Utils::Timer &timer, int &count)
273 {
274     BENCHMARK_LOGD("TimerTest void DoFunc2 is called.");
275     (void)timer.Register(
276         [&timer, &count]() {
277             count += 1;
278             if (count > MAX_COUNT) {
279                 return;
280             }
281             DoFunc2(timer, count);
282         },
283         TIMER_DELAY,
284         true);
285     g_data1++;
286 }
287 
BENCHMARK_F(BenchmarkTimerTest,testTimer009)288 BENCHMARK_F(BenchmarkTimerTest, testTimer009)(benchmark::State& state)
289 {
290     BENCHMARK_LOGD("TimerTest testTimer009 start.");
291     while (state.KeepRunning()) {
292         g_data1 = 0;
293         Utils::Timer timer("test_timer");
294         uint32_t ret = timer.Setup();
295         AssertEqual(Utils::TIMER_ERR_OK, ret, "Utils::TIMER_ERR_OK did not equal ret as expected.", state);
296 
297         int cnt = 0, cnt1 = 0;
298         DoFunc(timer, cnt);
299         DoFunc2(timer, cnt1);
300         std::this_thread::sleep_for(std::chrono::milliseconds(50));
301         AssertGreaterThanOrEqual(g_data1, 5, "g_data1 was not greater than or equal to 5 as expected.", state);
302         AssertGreaterThanOrEqual(14, g_data1, "g_data1 was not less than or equal to 14 as expected.", state);
303         std::this_thread::sleep_for(std::chrono::milliseconds(50));
304         timer.Shutdown();
305         AssertGreaterThanOrEqual(g_data1, 10, "g_data1 was not greater than or equal to 10 as expected.", state);
306     }
307     BENCHMARK_LOGD("TimerTest testTimer009 end.");
308 }
309 
310 /*
311  * @tc.name: testTimer010
312  * @tc.desc: once timer register
313  */
BENCHMARK_F(BenchmarkTimerTest,testTimer010)314 BENCHMARK_F(BenchmarkTimerTest, testTimer010)(benchmark::State& state)
315 {
316     BENCHMARK_LOGD("TimerTest testTimer010 start.");
317     while (state.KeepRunning()) {
318         g_data1 = 0;
319         Utils::Timer timer("test_timer");
320         uint32_t ret = timer.Setup();
321         AssertEqual(Utils::TIMER_ERR_OK, ret, "Utils::TIMER_ERR_OK did not equal ret as expected.", state);
322         timer.Register(TimeOutCallback1, 10, true);
323         timer.Register(TimeOutCallback1, 10);
324         timer.Register(TimeOutCallback1, 10, true);
325         timer.Register(TimeOutCallback1, 10);
326         std::this_thread::sleep_for(std::chrono::milliseconds(52));
327         timer.Shutdown();
328         AssertGreaterThanOrEqual(g_data1, 8, "g_data1 was not greater than or equal to 8 as expected.", state);
329     }
330     BENCHMARK_LOGD("TimerTest testTimer010 end.");
331 }
332 
333 /*
334  * @tc.name: testTimer011
335  * @tc.desc: once timer register
336  */
BENCHMARK_F(BenchmarkTimerTest,testTimer011)337 BENCHMARK_F(BenchmarkTimerTest, testTimer011)(benchmark::State& state)
338 {
339     BENCHMARK_LOGD("TimerTest testTimer011 start.");
340     while (state.KeepRunning()) {
341         g_data1 = 0;
342         Utils::Timer timer("test_timer");
343         uint32_t ret = timer.Setup();
344         AssertEqual(Utils::TIMER_ERR_OK, ret, "Utils::TIMER_ERR_OK did not equal ret as expected.", state);
345         timer.Register(TimeOutCallback1, 10);
346         timer.Register(TimeOutCallback1, 10, true);
347         timer.Register(TimeOutCallback1, 10);
348         timer.Register(TimeOutCallback1, 10, true);
349         std::this_thread::sleep_for(std::chrono::milliseconds(52));
350         timer.Shutdown();
351         AssertGreaterThanOrEqual(g_data1, 8, "g_data1 was not greater than or equal to 8 as expected.", state);
352     }
353     BENCHMARK_LOGD("TimerTest testTimer011 end.");
354 }
355 
356 /*
357  * @tc.name: testTimer012
358  * @tc.desc: Test double setup.
359  */
BENCHMARK_F(BenchmarkTimerTest,testTimer012)360 BENCHMARK_F(BenchmarkTimerTest, testTimer012)(benchmark::State& state)
361 {
362     BENCHMARK_LOGD("TimerTest testTimer012 start.");
363     while (state.KeepRunning()) {
364         g_data1 = 0;
365         Utils::Timer timer("test_timer");
366         uint32_t ret = timer.Setup();
367         AssertEqual(Utils::TIMER_ERR_OK, ret, "Utils::TIMER_ERR_OK did not equal ret as expected.", state);
368         ret = timer.Setup();
369         AssertEqual(Utils::TIMER_ERR_INVALID_VALUE, ret,
370             "Utils::TIMER_ERR_INVALID_VALUE did not equal ret as expected.", state);
371 
372         timer.Shutdown();
373     }
374     BENCHMARK_LOGD("TimerTest testTimer012 end.");
375 }
376 
377 /*
378  * @tc.name: testTimer013
379  * @tc.desc: Test uncommon operations.
380  */
BENCHMARK_F(BenchmarkTimerTest,testTimer013)381 BENCHMARK_F(BenchmarkTimerTest, testTimer013)(benchmark::State& state)
382 {
383     BENCHMARK_LOGD("TimerTest testTimer013 start.");
384     while (state.KeepRunning()) {
385         g_data1 = 0;
386         Utils::Timer timer("test_timer", -1);
387         uint32_t ret = timer.Setup();
388         BENCHMARK_LOGD("TimerTest testTimer013 Setup.");
389         AssertEqual(Utils::TIMER_ERR_OK, ret, "Utils::TIMER_ERR_OK did not equal ret as expected.", state);
390         std::this_thread::sleep_for(std::chrono::milliseconds(1));
391         timer.Shutdown(false);
392 
393         BENCHMARK_LOGD("TimerTest testTimer013 Shutdown.");
394 
395         Utils::Timer timer1("test_timer_1");
396         ret = timer1.Setup();
397         BENCHMARK_LOGD("TimerTest testTimer013 Setup1.");
398         AssertEqual(Utils::TIMER_ERR_OK, ret, "Utils::TIMER_ERR_OK did not equal ret as expected.", state);
399         std::this_thread::sleep_for(std::chrono::milliseconds(1));
400         timer1.Shutdown();
401         BENCHMARK_LOGD("TimerTest testTimer013 Shutdown false.");
402     }
403     BENCHMARK_LOGD("TimerTest testTimer013 end.");
404 }
405 }  // namespace
406 }  // namespace OHOS
407 // Run the benchmark
408 BENCHMARK_MAIN();