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 <sys/types.h>
18 #include <sys/timerfd.h>
19 #include <sys/prctl.h>
20 #include "unistd.h"
21 #include <cstdint>
22 #include <cstring>
23 #include <string>
24 #include <thread>
25 #include <mutex>
26 #include <memory>
27 #include <atomic>
28 #include <algorithm>
29 #include <list>
30 #include <map>
31 #include <functional>
32 #include <iostream>
33 #include "common_timer_errors.h"
34 #include "common_event_sys_errors.h"
35 #include "io_event_handler.h"
36 #include "io_event_reactor.h"
37 #include <sys/time.h>
38 #include "benchmark_log.h"
39 #include "benchmark_assert.h"
40 using namespace OHOS::Utils;
41 
42 namespace OHOS {
43 namespace {
44 
45 class BenchmarkEventTest : public benchmark::Fixture {
46 public:
BenchmarkEventTest()47     BenchmarkEventTest()
48     {
49         Iterations(iterations);
50         Repetitions(repetitions);
51         ReportAggregatesOnly();
52     }
53 
54     ~BenchmarkEventTest() override = default;
SetUp(const::benchmark::State & state)55     void SetUp(const ::benchmark::State& state) override
56     {
57     }
58 
TearDown(const::benchmark::State & state)59     void TearDown(const ::benchmark::State& state) override
60     {
61     }
62 
63 protected:
64     const int32_t repetitions = 3;
65     const int32_t iterations = 500;
66 };
67 
68 int g_data = 0;
TimerCallback1()69 void TimerCallback1()
70 {
71     g_data++;
72 }
73 
74 static const int MILLI_TO_BASE = 1000;
75 static const int NANO_TO_BASE = 1000000000;
76 static constexpr int MILLI_TO_NANO = NANO_TO_BASE / MILLI_TO_BASE;
77 const int INVALID_FD = -1;
78 const int SLEEP_SIXTEEN_MILLISECONDS = 16;
79 const int TIMER_INIT_DELAY = 15;
80 const int TIMER_INIT_DELAY_TEN = 10;
81 constexpr uint32_t TIMEOUT_ONE_MS = 1;
82 constexpr uint32_t TIMEOUT_TWO_MS = 2;
83 
84 
85 class TimerFdHandler : public IOEventHandler {
86 public:
87     using TimerEventCallback = std::function<void()>;
88     TimerFdHandler(int fd, const TimerEventCallback& cb);
~TimerFdHandler()89     ~TimerFdHandler() {}
90     bool Initialize(uint32_t interval);
91     void Uninitialize();
92     void TimeOut();
93 
94 private:
95     TimerEventCallback timerCallback_;
96 };
97 
TestCallback()98 void TestCallback()
99 {
100 }
101 
SetFdAndCallback(std::shared_ptr<IOEventHandler> & handler,benchmark::State & state)102 void SetFdAndCallback(std::shared_ptr<IOEventHandler>& handler, benchmark::State& state)
103 {
104     // 1. Set fd
105     int fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
106     AssertUnequal(fd, INVALID_FD, "fd was not different from INVALID_FD as expected.", state);
107     handler->SetFd(fd);
108     AssertEqual(handler->GetFd(), fd, "handler->GetFd() did not equal fd as expected.", state);
109 
110     // 2. Set callback
111     handler->SetCallback(&TestCallback);
112     AssertUnequal(handler->GetCallback(), nullptr,
113         "handler->GetCallback() was not different from nullptr as expected.", state);
114 }
115 
116 /*
117  * @tc.name: testIOEventHandler001
118  * @tc.desc: test basic interfaces of IOEventHandler.
119  */
BENCHMARK_F(BenchmarkEventTest,testIOEventHandler001)120 BENCHMARK_F(BenchmarkEventTest, testIOEventHandler001)(benchmark::State& state)
121 {
122     BENCHMARK_LOGD("EventTest testIOEventHandler001 start.");
123     while (state.KeepRunning()) {
124         g_data = 0;
125         // 1. Create io event handler
126         std::shared_ptr<IOEventHandler> handler = std::make_shared<IOEventHandler>(INVALID_FD);
127 
128         // 2. Set fd and callback
129         SetFdAndCallback(handler, state);
130 
131         // 3. Set interest events
132         handler->SetEvents(Events::EVENT_READ | Events::EVENT_WRITE);
133         AssertEqual(handler->GetEvents(), (Events::EVENT_READ | Events::EVENT_WRITE),
134             "handler->GetEvents() did not equal (Events::EVENT_READ | Events::EVENT_WRITE) as expected.", state);
135 
136         // 4. Check status
137         AssertEqual(handler->Prev(), nullptr, "handler->Prev() did not equal nullptr as expected.", state);
138         AssertEqual(handler->Next(), nullptr, "handler->Next() did not equal nullptr as expected.", state);
139         AssertEqual(handler->IsActive(), false, "handler->IsActive() did not equal false as expected.", state);
140 
141         // 5. disable events
142         handler->DisableAll();
143         AssertEqual(handler->GetEvents(), Events::EVENT_NONE,
144             "handler->GetEvents() did not equal Events::EVENT_NONE as expected.", state);
145 
146         // 6. enable events
147         handler->EnableRead();
148         handler->EnableWrite();
149         AssertEqual(handler->GetEvents(), (Events::EVENT_READ | Events::EVENT_WRITE),
150             "handler->GetEvents() did not equal (Events::EVENT_READ | Events::EVENT_WRITE) as expected.", state);
151 
152         // 7. disable one of the events
153         handler->DisableWrite();
154         AssertEqual(handler->GetEvents(), Events::EVENT_READ,
155             "handler->GetEvents() did not equal Events::EVENT_READ as expected.", state);
156     }
157     BENCHMARK_LOGD("EventTest testIOEventHandler001 end.");
158 }
159 
160 /*
161  * @tc.name: testIOEventHandler002
162  * @tc.desc: test reactor-related interfaces of IOEventHandler.
163  */
BENCHMARK_F(BenchmarkEventTest,testIOEventHandler002)164 BENCHMARK_F(BenchmarkEventTest, testIOEventHandler002)(benchmark::State& state)
165 {
166     BENCHMARK_LOGD("EventTest testIOEventHandler002 start.");
167     while (state.KeepRunning()) {
168         g_data = 0;
169         // 1. Create io event handler
170         std::shared_ptr<IOEventHandler> handler = std::make_shared<IOEventHandler>(INVALID_FD);
171 
172         // 2. Set fd and callback
173         SetFdAndCallback(handler, state);
174 
175         // 3. Set interest events
176         handler->EnableRead();
177         AssertEqual(handler->GetEvents(), Events::EVENT_READ,
178             "handler->GetEvents() did not equal Events::EVENT_READ as expected.", state);
179 
180         // 4. Create a reactor but not run
181         std::shared_ptr<IOEventReactor> reactor = std::make_shared<IOEventReactor>();
182         AssertEqual(reactor->SetUp(), EVENT_SYS_ERR_OK,
183             "reactor->SetUp() did not equal EVENT_SYS_ERR_OK as expected.", state);
184 
185         // 5. Start handler
186         handler->Start(reactor.get());
187         AssertEqual(reactor->FindHandler(handler.get()), EVENT_SYS_ERR_OK,
188             "reactor->FindHandler(handler.get()) did not equal EVENT_SYS_ERR_OK as expected.", state);
189 
190         // 6. Change setting and update handler to the reactor
191         handler->EnableWrite();
192         AssertTrue((handler->Update(reactor.get())),
193             "handler->Update(reactor.get()) did not equal true as expected.", state);
194 
195         // 7. Remove the handler
196         handler->Stop(reactor.get());
197         AssertEqual(reactor->FindHandler(handler.get()), EVENT_SYS_ERR_NOT_FOUND,
198             "reactor->FindHandler(handler.get()) did not equal EVENT_SYS_ERR_NOT_FOUND as expected.", state);
199 
200         // 8. Add handler, then delete handler. handler will remove itself from the reactor during deconstruction.
201         AssertTrue((handler->Start(reactor.get())),
202             "handler->Start(reactor.get()) did not equal true as expected.", state);
203         handler.reset();
204     }
205     BENCHMARK_LOGD("EventTest testIOEventHandler002 end.");
206 }
207 
AddHandler(std::shared_ptr<IOEventReactor> & reactor,std::shared_ptr<IOEventHandler> & handler1,std::shared_ptr<IOEventHandler> & handler2,std::shared_ptr<IOEventHandler> & handler3,benchmark::State & state)208 static void AddHandler(std::shared_ptr<IOEventReactor>& reactor, std::shared_ptr<IOEventHandler>& handler1,
209                        std::shared_ptr<IOEventHandler>& handler2, std::shared_ptr<IOEventHandler>& handler3,
210                        benchmark::State& state)
211 {
212     AssertEqual(reactor->AddHandler(handler1.get()), EVENT_SYS_ERR_OK,
213         "reactor->AddHandler(handler1.get()) did not equal EVENT_SYS_ERR_OK as expected.", state);
214     AssertEqual(reactor->AddHandler(handler2.get()), EVENT_SYS_ERR_OK,
215         "reactor->AddHandler(handler2.get()) did not equal EVENT_SYS_ERR_OK as expected.", state);
216     AssertUnequal(reactor->AddHandler(handler3.get()), EVENT_SYS_ERR_OK,
217         "reactor->AddHandler(handler3.get()) was not different from EVENT_SYS_ERR_OK as expected.", state);
218     AssertUnequal(reactor->AddHandler(nullptr), EVENT_SYS_ERR_OK,
219         "reactor->AddHandler(nullptr) was not different from EVENT_SYS_ERR_OK as expected.", state);
220 }
221 
RemoveHandler(std::shared_ptr<IOEventReactor> & reactor,std::shared_ptr<IOEventHandler> & handler2,std::shared_ptr<IOEventHandler> & handler3,std::shared_ptr<IOEventHandler> & handler4,benchmark::State & state)222 static void RemoveHandler(std::shared_ptr<IOEventReactor>& reactor, std::shared_ptr<IOEventHandler>& handler2,
223                           std::shared_ptr<IOEventHandler>& handler3, std::shared_ptr<IOEventHandler>& handler4,
224                           benchmark::State& state)
225 {
226     AssertUnequal(reactor->RemoveHandler(nullptr), EVENT_SYS_ERR_OK,
227         "reactor->RemoveHandler(nullptr) was not different from EVENT_SYS_ERR_OK as expected.", state);
228     AssertUnequal(reactor->RemoveHandler(handler3.get()), EVENT_SYS_ERR_OK,
229         "reactor->RemoveHandler(handler3.get()) was not different from EVENT_SYS_ERR_OK as expected.", state);
230     AssertUnequal(reactor->RemoveHandler(handler4.get()), EVENT_SYS_ERR_OK,
231         "reactor->RemoveHandler(handler4.get()) was not different from EVENT_SYS_ERR_OK as expected.", state);
232     AssertEqual(reactor->RemoveHandler(handler2.get()), EVENT_SYS_ERR_OK,
233         "reactor->RemoveHandler(handler2.get()) did not equal EVENT_SYS_ERR_OK as expected.", state);
234 }
235 
UpdateHandler(std::shared_ptr<IOEventReactor> & reactor,std::shared_ptr<IOEventHandler> & handler1,std::shared_ptr<IOEventHandler> & handler3,std::shared_ptr<IOEventHandler> & handler4,benchmark::State & state)236 static void UpdateHandler(std::shared_ptr<IOEventReactor>& reactor, std::shared_ptr<IOEventHandler>& handler1,
237                           std::shared_ptr<IOEventHandler>& handler3, std::shared_ptr<IOEventHandler>& handler4,
238                           benchmark::State& state)
239 {
240     // Update handler
241     AssertUnequal(reactor->UpdateHandler(nullptr), EVENT_SYS_ERR_OK,
242         "reactor->UpdateHandler(nullptr) was not different from EVENT_SYS_ERR_OK as expected.", state);
243     AssertUnequal(reactor->UpdateHandler(handler3.get()), EVENT_SYS_ERR_OK,
244         "reactor->UpdateHandler(handler3.get()) was not different from EVENT_SYS_ERR_OK as expected.", state);
245     AssertEqual(reactor->UpdateHandler(handler1.get()), EVENT_SYS_ERR_OK,
246         "reactor->UpdateHandler(handler1.get()) did not equal EVENT_SYS_ERR_OK as expected.", state);
247     AssertEqual(reactor->UpdateHandler(handler4.get()), EVENT_SYS_ERR_OK,
248         "reactor->UpdateHandler(handler4.get()) did not equal EVENT_SYS_ERR_OK as expected.", state);
249 }
250 
251 /*
252  * @tc.name: testIOEventReactor001
253  * @tc.desc: test basic interfaces of IOEventReactor.
254  */
BENCHMARK_F(BenchmarkEventTest,testIOEventReactor001)255 BENCHMARK_F(BenchmarkEventTest, testIOEventReactor001)(benchmark::State& state)
256 {
257     BENCHMARK_LOGD("EventTest testIOEventReactor001 start.");
258     while (state.KeepRunning()) {
259         g_data = 0;
260         // Get fd
261         int fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
262         AssertUnequal(fd, INVALID_FD, "fd was not different from INVALID_FD as expected.", state);
263 
264         // 1. Create io event handlers
265         std::shared_ptr<IOEventHandler> handler1 = std::make_shared<IOEventHandler>(fd);
266         std::shared_ptr<IOEventHandler> handler2 = std::make_shared<IOEventHandler>(fd);
267         std::shared_ptr<IOEventHandler> handler3 = std::make_shared<IOEventHandler>(INVALID_FD);
268         std::shared_ptr<IOEventHandler> handler4 = std::make_shared<IOEventHandler>(fd);
269 
270         // 2. Create a reactor but not run
271         std::shared_ptr<IOEventReactor> reactor = std::make_shared<IOEventReactor>();
272         AssertEqual(reactor->SetUp(), EVENT_SYS_ERR_OK,
273             "reactor->SetUp() did not equal EVENT_SYS_ERR_OK as expected.", state);
274 
275         // 3. Add handler
276         AddHandler(reactor, handler1, handler2, handler3, state);
277 
278         // 4. Add handler from the handler side.
279         AssertUnequal(handler1->Start(reactor.get()), true,
280             "handler1->Start(reactor.get()) was not different from false as expected.", state);
281         AssertUnequal(handler3->Start(reactor.get()), true,
282             "handler3->Start(reactor.get()) was not different from false as expected.", state);
283 
284         // 5. Remove handler
285         RemoveHandler(reactor, handler2, handler3, handler4, state);
286 
287         // 6. Remove handler from the handler side.
288         AssertUnequal(handler2->Stop(reactor.get()), true,
289             "handler2->Stop(reactor.get()) was not different from false as expected.", state);
290 
291         // 7. Update handler
292         UpdateHandler(reactor, handler1, handler3, handler4, state);
293 
294         // Update handler from the handler side.
295         AssertEqual(handler2->Update(reactor.get()), true,
296             "handler2->Update(reactor.get()) was not different from false as expected.", state);
297         AssertUnequal(handler3->Update(reactor.get()), true,
298             "handler3->Update(reactor.get()) was not different from true as expected.", state);
299 
300         // 9. Find handler
301         AssertUnequal(reactor->FindHandler(nullptr), EVENT_SYS_ERR_OK,
302             "reactor->FindHandler(nullptr) was not different from EVENT_SYS_ERR_OK as expected.", state);
303         AssertUnequal(reactor->FindHandler(handler3.get()), EVENT_SYS_ERR_OK,
304             "reactor->FindHandler(handler3.get()) was not different from EVENT_SYS_ERR_OK as expected.", state);
305 
306         // 10. Clean handler
307         AssertUnequal(reactor->Clean(INVALID_FD), EVENT_SYS_ERR_OK,
308             "reactor->Clean(INVALID_FD) was not different from EVENT_SYS_ERR_OK as expected.", state);
309         AssertEqual(reactor->Clean(fd), EVENT_SYS_ERR_OK,
310             "reactor->Clean(fd) did not equal EVENT_SYS_ERR_OK as expected.", state);
311     }
312     BENCHMARK_LOGD("EventTest testIOEventReactor001 end.");
313 }
314 
315 /*
316  * @tc.name: testIOEventReactor002
317  * @tc.desc: test change event but not update.
318  */
BENCHMARK_F(BenchmarkEventTest,testIOEventReactor002)319 BENCHMARK_F(BenchmarkEventTest, testIOEventReactor002)(benchmark::State& state)
320 {
321     BENCHMARK_LOGD("EventTest testIOEventReactor002 start.");
322     while (state.KeepRunning()) {
323         g_data = 0;
324         // 1. Open timer
325         int fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
326         AssertUnequal(fd, INVALID_FD, "fd was not different from INVALID_FD as expected.", state);
327 
328         // 2. Create io event handlers
329         std::shared_ptr<IOEventHandler> handler1 = std::make_shared<IOEventHandler>(fd);
330         std::shared_ptr<IOEventHandler> handler2 = std::make_shared<IOEventHandler>(fd);
331 
332         // 3. Create a reactor but not run
333         std::unique_ptr<IOEventReactor> reactor = std::make_unique<IOEventReactor>();
334         AssertEqual(reactor->SetUp(), EVENT_SYS_ERR_OK,
335             "reactor->SetUp() did not equal EVENT_SYS_ERR_OK as expected.", state);
336 
337         // 4. Add handler
338         AssertEqual(reactor->AddHandler(handler1.get()), EVENT_SYS_ERR_OK,
339             "reactor->AddHandler(handler1.get()) did not equal EVENT_SYS_ERR_OK as expected.", state);
340         AssertEqual(reactor->AddHandler(handler2.get()), EVENT_SYS_ERR_OK,
341             "reactor->AddHandler(handler2.get()) did not equal EVENT_SYS_ERR_OK as expected.", state);
342 
343         // 5. release one handler
344         handler2.reset(); // will be removed from the inner list.
345     }
346     BENCHMARK_LOGD("EventTest testIOEventReactor002 end.");
347 }
348 
TimerFdHandler(int fd,const TimerEventCallback & cb)349 TimerFdHandler::TimerFdHandler(int fd, const TimerEventCallback& cb)
350     : IOEventHandler(fd),  timerCallback_(cb)
351 {
352     BENCHMARK_LOGD("EventTest TimerFdHandler::TimerFdHandler is called.");
353 }
354 
Initialize(uint32_t interval)355 bool TimerFdHandler::Initialize(uint32_t interval)
356 {
357     BENCHMARK_LOGD("EventTest bool TimerFdHandler::Initialize is called.");
358     if ((GetFd() == INVALID_FD)) {
359         return false;
360     }
361 
362     struct itimerspec newValue = {{0, 0}, {0, 0}};
363     timespec now{0, 0};
364     if (clock_gettime(CLOCK_MONOTONIC, &now) == INVALID_FD) {
365         return false;
366     }
367 
368     // next time out time is now + interval
369     newValue.it_value.tv_sec = now.tv_sec + interval / MILLI_TO_BASE;
370     newValue.it_value.tv_nsec = now.tv_nsec + (interval % MILLI_TO_BASE) * MILLI_TO_NANO;
371     if (newValue.it_value.tv_nsec >= NANO_TO_BASE) {
372         newValue.it_value.tv_sec += 1;
373         newValue.it_value.tv_nsec = newValue.it_value.tv_nsec % NANO_TO_BASE;
374     }
375 
376     // interval
377     newValue.it_interval.tv_sec  = interval / MILLI_TO_BASE;
378     newValue.it_interval.tv_nsec = (interval % MILLI_TO_BASE) * MILLI_TO_NANO;
379 
380     if (timerfd_settime(GetFd(), TFD_TIMER_ABSTIME, &newValue, nullptr) == INVALID_FD) {
381         BENCHMARK_LOGD("Set timerFd failed-%{public}s timer_fd:%{public}d", strerror(errno), GetFd());
382         return false;
383     }
384 
385     EnableRead();
386     SetCallback(std::bind(&TimerFdHandler::TimeOut, this));
387 
388     return true;
389 }
390 
Uninitialize()391 void TimerFdHandler::Uninitialize()
392 {
393     BENCHMARK_LOGD("EventTest void TimerFdHandler::Uninitialize is called.");
394     DisableAll();
395 }
396 
TimeOut()397 void TimerFdHandler::TimeOut()
398 {
399     BENCHMARK_LOGD("EventTest void TimerFdHandler::TimeOut is called.");
400     if (GetFd() == INVALID_FD) {
401         BENCHMARK_LOGD("Invalid timer_fd.");
402         return;
403     }
404     uint64_t expirations = 0;
405     ssize_t n = ::read(GetFd(), &expirations, sizeof(expirations));
406     if (n != sizeof(expirations)) {
407         BENCHMARK_LOGD("reads %{public}d bytes instead of 8.", static_cast<int>(n));
408     }
409 
410     if (timerCallback_) {
411         timerCallback_();
412     }
413 }
414 
415 /*
416  * @tc.name: testEvent001
417  * @tc.desc: test handling event of timerfd.
418  */
BENCHMARK_F(BenchmarkEventTest,testEvent001)419 BENCHMARK_F(BenchmarkEventTest, testEvent001)(benchmark::State& state)
420 {
421     BENCHMARK_LOGD("EventTest testEvent001 start.");
422     while (state.KeepRunning()) {
423         g_data = 0;
424         // 1. Open timer
425         int fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
426         AssertUnequal(fd, INVALID_FD, "fd was not different from INVALID_FD as expected.", state);
427         // 2. Create timer event handler
428         std::shared_ptr<TimerFdHandler> handler = std::make_shared<TimerFdHandler>(fd, &TimerCallback1);
429 
430         // 3. Create reactor for event loop
431         std::unique_ptr<IOEventReactor> reactor = std::make_unique<IOEventReactor>();
432         AssertEqual(reactor->SetUp(), EVENT_SYS_ERR_OK,
433             "reactor->SetUp() did not equal EVENT_SYS_ERR_OK as expected.", state);
434         reactor->EnableHandling();
435 
436         // 4. Initialize timer handler and add it to reactor
437         AssertTrue((handler->Initialize(10)), "handler->Initialize(10) did not equal true as expected.", state);
438         AssertTrue((handler->Start(reactor.get())),
439             "handler->Start(reactor.get()) did not equal true as expected.", state);
440 
441         // 5. Run event loop
442         std::thread loopThread([&reactor] {
443             reactor->Run(INVALID_FD);
444         });
445 
446         // 6. Wait for event handling
447         std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_SIXTEEN_MILLISECONDS));
448 
449         // 7. Check result, execute once at least
450         AssertGreaterThanOrEqual(g_data, 1, "g_data was not greater than or equal to 1 as expected.", state);
451 
452         // 8. terminate the event-loop (aka Run())
453         reactor->Terminate();
454         loopThread.join();
455     }
456     BENCHMARK_LOGD("EventTest testEvent001 end.");
457 }
458 
EventLoop(std::shared_ptr<TimerFdHandler> & handler,benchmark::State & state,std::thread & loopThread)459 std::unique_ptr<IOEventReactor> EventLoop(std::shared_ptr<TimerFdHandler>& handler, benchmark::State& state,
460     std::thread& loopThread)
461 {
462     // 1. Open timer
463     int fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
464     AssertUnequal(fd, INVALID_FD, "fd was not different from INVALID_FD as expected.", state);
465     // 2. Create timer event handler
466     handler = std::make_shared<TimerFdHandler>(fd, &TimerCallback1);
467 
468     // 3. Create reactor for event loop
469     std::unique_ptr<IOEventReactor> reactor = std::make_unique<IOEventReactor>();
470     AssertEqual(reactor->SetUp(), EVENT_SYS_ERR_OK,
471         "reactor->SetUp() did not equal EVENT_SYS_ERR_OK as expected.", state);
472 
473     // 4. Initialize timer handler and add it to reactor
474     AssertTrue((handler->Initialize(TIMER_INIT_DELAY_TEN)),
475         "handler->Initialize(TIMER_INIT_DELAY_TEN) did not equal true as expected.", state);
476     AssertTrue((handler->Start(reactor.get())),
477         "handler->Start(reactor.get()) did not equal true as expected.", state);
478 
479     // 5. Run event loop
480     loopThread = std::thread([&reactor] {
481         reactor->Run(INVALID_FD);
482     });
483 
484     return reactor;
485 }
486 
487 /*
488  * @tc.name: testEvent002
489  * @tc.desc: test changing event to EVENT_NONE.
490  */
BENCHMARK_F(BenchmarkEventTest,testEvent002)491 BENCHMARK_F(BenchmarkEventTest, testEvent002)(benchmark::State& state)
492 {
493     BENCHMARK_LOGD("EventTest testEvent002 start.");
494     while (state.KeepRunning()) {
495         g_data = 0;
496         std::shared_ptr<TimerFdHandler> handler;
497         std::thread loopThread;
498         // 1. event loop
499         std::unique_ptr<IOEventReactor> reactor = EventLoop(handler, state, loopThread);
500 
501         // 2. Change settings
502         reactor->DisableHandling();
503         std::this_thread::sleep_for(std::chrono::milliseconds(1));
504         reactor->EnableHandling();
505         handler->SetEvents(Events::EVENT_NONE);
506 
507         // 3. Wait for event handling
508         std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_SIXTEEN_MILLISECONDS));
509 
510         // 4. Check result, no execution
511         AssertEqual(g_data, 0, "g_data did not equal 0 as expected.", state);
512 
513         // 5. terminate the event-loop (aka Run())
514         reactor->Terminate();
515         loopThread.join();
516     }
517     BENCHMARK_LOGD("EventTest testEvent002 end.");
518 }
519 
520 /*
521  * @tc.name: testEvent003
522  * @tc.desc: test disable single event.
523  */
BENCHMARK_F(BenchmarkEventTest,testEvent003)524 BENCHMARK_F(BenchmarkEventTest, testEvent003)(benchmark::State& state)
525 {
526     BENCHMARK_LOGD("EventTest testEvent003 start.");
527     while (state.KeepRunning()) {
528         g_data = 0;
529         std::shared_ptr<TimerFdHandler> handler;
530         std::thread loopThread;
531         // 1. event loop
532         std::unique_ptr<IOEventReactor> reactor = EventLoop(handler, state, loopThread);
533 
534         // 2. Change settings
535         reactor->EnableHandling();
536         AssertTrue((handler->Stop(reactor.get())),
537             "handler->Stop(reactor.get()) did not equal true as expected.", state);
538 
539         // 3. Check result, no execution
540         AssertEqual(g_data, 0, "g_data did not equal 0 as expected.", state);
541 
542         // 4. terminate the event-loop (aka Run())
543         reactor->Terminate();
544         loopThread.join();
545     }
546     BENCHMARK_LOGD("EventTest testEvent003 end.");
547 }
548 
549 /*
550  * @tc.name: testEvent004
551  * @tc.desc: test removing callback.
552  */
BENCHMARK_F(BenchmarkEventTest,testEvent004)553 BENCHMARK_F(BenchmarkEventTest, testEvent004)(benchmark::State& state)
554 {
555     BENCHMARK_LOGD("EventTest testEvent004 start.");
556     while (state.KeepRunning()) {
557         g_data = 0;
558         std::shared_ptr<TimerFdHandler> handler;
559         std::thread loopThread;
560         // 1. event loop
561         std::unique_ptr<IOEventReactor> reactor = EventLoop(handler, state, loopThread);
562 
563         // 2. Change settings
564         reactor->EnableHandling();
565         handler->SetCallback(nullptr);
566 
567         // 3. Wait for event handling
568         std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_SIXTEEN_MILLISECONDS));
569 
570         // 4. Check result, no execution
571         AssertEqual(g_data, 0, "g_data did not equal 0 as expected.", state);
572 
573         // 5. terminate the event-loop (aka Run())
574         reactor->Terminate();
575         loopThread.join();
576     }
577     BENCHMARK_LOGD("EventTest testEvent004 end.");
578 }
579 
580 /*
581  * @tc.name: testEvent005
582  * @tc.desc: test change event but not update.
583  */
BENCHMARK_F(BenchmarkEventTest,testEvent005)584 BENCHMARK_F(BenchmarkEventTest, testEvent005)(benchmark::State& state)
585 {
586     BENCHMARK_LOGD("EventTest testEvent005 start.");
587     while (state.KeepRunning()) {
588         g_data = 0;
589         // 1. Open timer
590         int fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
591         AssertUnequal(fd, INVALID_FD, "fd was not different from INVALID_FD as expected.", state);
592         // 2. Create timer event handler
593         std::shared_ptr<TimerFdHandler> handler = std::make_shared<TimerFdHandler>(fd, &TimerCallback1);
594 
595         // 3. Create reactor for event loop
596         std::unique_ptr<IOEventReactor> reactor = std::make_unique<IOEventReactor>();
597         AssertEqual(reactor->SetUp(), EVENT_SYS_ERR_OK,
598             "reactor->SetUp() did not equal EVENT_SYS_ERR_OK as expected.", state);
599 
600         // 4. Initialize timer handler and add it to reactor
601         AssertTrue((handler->Initialize(TIMER_INIT_DELAY)),
602             "handler->Initialize(TIMER_INIT_DELAY) did not equal true as expected.", state);
603         AssertTrue((handler->Start(reactor.get())),
604             "handler->Start(reactor.get()) did not equal true as expected.", state);
605 
606         // 5. Run event loop
607         std::thread loopThread([&reactor] {
608             reactor->Run(INVALID_FD);
609         });
610 
611         // 6. Change settings but not update
612         handler->SetEvents(Events::EVENT_WRITE);
613         reactor->EnableHandling();
614 
615         // 7. Wait for event handling
616         std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_SIXTEEN_MILLISECONDS));
617 
618         // 8. Check result, no execution
619         AssertEqual(g_data, 0, "g_data did not equal 0 as expected.", state);
620 
621         // 9. terminate the event-loop (aka Run())
622         reactor->Terminate();
623         loopThread.join();
624     }
625     BENCHMARK_LOGD("EventTest testEvent005 end.");
626 }
627 
628 /*
629  * @tc.name: testEvent006
630  * @tc.desc: test release the handler when started.
631  */
BENCHMARK_F(BenchmarkEventTest,testEvent006)632 BENCHMARK_F(BenchmarkEventTest, testEvent006)(benchmark::State& state)
633 {
634     BENCHMARK_LOGD("EventTest testEvent006 start.");
635     while (state.KeepRunning()) {
636         g_data = 0;
637         // 1. Open timer
638         int fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
639         AssertUnequal(fd, INVALID_FD, "fd was not different from INVALID_FD as expected.", state);
640         // 2. Create timer event handler
641         std::shared_ptr<TimerFdHandler> handler = std::make_shared<TimerFdHandler>(fd, &TimerCallback1);
642 
643         // 3. Create reactor for event loop
644         std::unique_ptr<IOEventReactor> reactor = std::make_unique<IOEventReactor>();
645         AssertEqual(reactor->SetUp(), EVENT_SYS_ERR_OK,
646             "reactor->SetUp() did not equal EVENT_SYS_ERR_OK as expected.", state);
647 
648         // 4. Initialize timer handler and add it to reactor
649         AssertTrue((handler->Initialize(TIMER_INIT_DELAY)),
650             "handler->Initialize(TIMER_INIT_DELAY) did not equal true as expected.", state);
651         AssertTrue((handler->Start(reactor.get())),
652             "handler->Start(reactor.get()) did not equal true as expected.", state);
653 
654         // 5. Run event loop
655         std::thread loopThread([&reactor] {
656             reactor->Run(INVALID_FD);
657         });
658 
659         // 6. release eventhandler
660         handler.reset();
661         reactor->EnableHandling();
662 
663         // 7. Wait for event handling
664         std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_SIXTEEN_MILLISECONDS));
665 
666         // 8. Check result, no execution
667         AssertEqual(g_data, 0, "g_data did not equal 0 as expected.", state);
668 
669         // 9. terminate the event-loop (aka Run())
670         reactor->Terminate();
671         loopThread.join();
672     }
673     BENCHMARK_LOGD("EventTest testEvent006 end.");
674 }
675 
676 // Try to substitue underlying implementation of OHOS::UTILS::TIMER
677 class TimerEventHandler {
678 public:
679     using TimerEventCallback = std::function<void(TimerEventHandler*)>;
680     TimerEventHandler(int timerFd, uint32_t timeout, bool once);
681     TimerEventHandler(uint32_t timeout /* ms */, bool once);
682     ~TimerEventHandler();
683 
684     TimerEventHandler(const TimerEventHandler&) = delete;
685     TimerEventHandler& operator=(const TimerEventHandler&) = delete;
686     TimerEventHandler(const TimerEventHandler&&) = delete;
687     TimerEventHandler& operator=(const TimerEventHandler&&) = delete;
688 
689     ErrCode Initialize();
690     void Uninitialize();
691 
692     bool Start(IOEventReactor* reactor);
693     bool Stop(IOEventReactor* reactor);
694 
SetTimerEventCallback(const TimerEventCallback & callback)695     inline void SetTimerEventCallback(const TimerEventCallback& callback) { timerEventCallback_ = callback; }
696 
SetTimerId(const uint32_t & id)697     inline void SetTimerId(const uint32_t& id) { timerId_ = id; }
698 
GetInterval() const699     inline uint32_t GetInterval() const { return interval_; }
GetTimerId() const700     inline uint32_t GetTimerId() const { return timerId_; }
GetTimerFd() const701     inline int GetTimerFd() const { return handler_->GetFd(); }
702 
703 private:
704     void TimeOut();
705 
706 private:
707     bool           once_;
708     uint32_t       timerId_;
709     uint32_t       interval_;
710     TimerEventCallback  timerEventCallback_;
711 
712     std::unique_ptr<IOEventHandler> handler_;
713 
714     friend class Timer;
715 };
716 
717 class Timer {
718 public:
719     using TimerCallback = std::function<void ()>;
720     using TimerCallbackPtr = std::shared_ptr<TimerCallback>;
721     using TimerEventCallback = TimerEventHandler::TimerEventCallback;
722 
723     explicit Timer(const std::string& name, int timeoutMs = 1000);
~Timer()724     virtual ~Timer() {}
725     virtual uint32_t Setup();
726     virtual void Shutdown(bool useJoin = true);
727     uint32_t Register(const TimerCallback& callback, uint32_t interval /* ms */, bool once = false);
728     void Unregister(uint32_t timerId);
729 
730 private:
731     void MainLoop();
732     void OnTimer(TimerEventHandler* handler, const TimerCallback& callback);
733     uint32_t GetValidId() const;
734     int GetTimerFd(uint32_t interval /* ms */);
735     void EraseUnusedTimerId(uint32_t interval, const std::vector<uint32_t>& unusedIds);
736 
737 private:
738     using TimerHandlerPtr = std::shared_ptr<TimerEventHandler>;
739     using TimerHandlerList = std::list<TimerHandlerPtr>;
740 
741     ErrCode ScheduleTimer(const TimerEventCallback& callback, uint32_t interval, uint32_t timerId, int& timerFd,
742                           bool once);
743     ErrCode CancelTimer(TimerHandlerPtr target);
744 
745     std::map<uint32_t, TimerHandlerPtr> timerHandlers_;
746     std::map<uint32_t, TimerHandlerList> intervalToTimers_;
747 
748     std::string name_;
749     int timeoutMs_;
750     std::thread thread_;
751     std::unique_ptr<IOEventReactor> reactor_;
752     std::mutex mutex_;
753 };
754 
Timer(const std::string & name,int timeoutMs)755 Timer::Timer(const std::string& name, int timeoutMs) : name_(name), timeoutMs_(timeoutMs),
756     reactor_(new IOEventReactor())
757 {
758     BENCHMARK_LOGD("EventTest Timer::Timer is called.");
759 }
760 
MainLoop()761 void Timer::MainLoop()
762 {
763     prctl(PR_SET_NAME, name_.c_str(), 0, 0, 0);
764 
765     reactor_->Run(timeoutMs_);
766     BENCHMARK_LOGD("||%{public}d||Loop finished", gettid());
767     BENCHMARK_LOGD("MainLoop timeoutMs_: %{public}d", timeoutMs_);
768 
769     if (reactor_->CleanUp() != EVENT_SYS_ERR_OK) {
770         BENCHMARK_LOGD("||%{public}d||Reactor Clean Failed. It will clean during deconstruction", gettid());
771     }
772 }
773 
Setup()774 uint32_t Timer::Setup()
775 {
776     BENCHMARK_LOGD("EventTest uint32_t Timer::Setup is called.");
777     if (thread_.joinable()) { // avoid double assign to an active thread
778         return TIMER_ERR_INVALID_VALUE;
779     }
780 
781     if (reactor_->SetUp() != EVENT_SYS_ERR_OK) {
782         BENCHMARK_LOGD("||%{public}d||Setup reactor failed.", gettid());
783         return TIMER_ERR_DEAL_FAILED;
784     }
785 
786     reactor_->EnableHandling();
787 
788     std::thread loopThread(std::bind(&Timer::MainLoop, this));
789     thread_.swap(loopThread);
790 
791     return TIMER_ERR_OK;
792 }
793 
Shutdown(bool useJoin)794 void Timer::Shutdown(bool useJoin)
795 {
796     BENCHMARK_LOGD("EventTest void Timer::Shutdown is called.");
797     if (!thread_.joinable()) {
798         BENCHMARK_LOGD("||%{public}d||Invalid operation. Already shutdown.", gettid());
799         return;
800     }
801 
802     BENCHMARK_LOGD("||%{public}d||Stop reactor.", gettid());
803     reactor_->Terminate();
804 
805     if (!useJoin) {
806         thread_.detach();
807         return;
808     }
809     thread_.join();
810 }
811 
ScheduleTimer(const TimerEventCallback & callback,uint32_t interval,uint32_t timerId,int & timerFd,bool once)812 ErrCode Timer::ScheduleTimer(const TimerEventCallback& callback, uint32_t interval,
813                              uint32_t timerId, int& timerFd, bool once)
814 {
815     BENCHMARK_LOGD("EventTest ErrCode Timer::ScheduleTimer is called.");
816     std::shared_ptr<TimerEventHandler> handler = std::make_shared<TimerEventHandler>(timerFd, interval, once);
817     BENCHMARK_LOGD("Timer::ScheduleTimer interval: %{public}u -- timerId: %{public}u -- timerFd: %{public}d",
818         interval, timerId, timerFd);
819 
820     handler->SetTimerId(timerId);
821     handler->SetTimerEventCallback(callback);
822 
823     uint32_t ret = handler->Initialize();
824     if (ret != TIMER_ERR_OK) {
825         BENCHMARK_LOGD("||%{public}d||Init timer handler failed.", gettid());
826         return ret;
827     }
828     if (!handler->Start(reactor_.get())) {
829         BENCHMARK_LOGD("||%{public}d||Start timer handler failed.", gettid());
830         return TIMER_ERR_DEAL_FAILED;
831     }
832     timerHandlers_.emplace(timerId, handler); // Add to the id2handlers map
833     intervalToTimers_[interval].push_back(handler); // Add to interval2handlerlist map
834     timerFd = handler->GetTimerFd();
835     return TIMER_ERR_OK;
836 }
837 
838 
Register(const TimerCallback & callback,uint32_t interval,bool once)839 uint32_t Timer::Register(const TimerCallback& callback, uint32_t interval /* ms */, bool once)
840 {
841     BENCHMARK_LOGD("EventTest uint32_t Timer::Register is called.");
842     std::lock_guard<std::mutex> lock(mutex_);
843 
844     // wrap the callback in OnTiner
845     TimerEventCallback wrappedCb = std::bind(&Timer::OnTimer, this, std::placeholders::_1, callback);
846     int timerFd = once ? IO_EVENT_INVALID_FD : GetTimerFd(interval); // Get timerFd
847     uint32_t timerId = GetValidId();                        // Get timerId
848 
849     uint32_t ret = ScheduleTimer(wrappedCb, interval, timerId, timerFd, once);
850     if (ret != TIMER_ERR_OK) {
851         BENCHMARK_LOGD("||%{public}d||Try schedule task failed. timer-id:%{public}d, interval:%{public}d, "\
852             "timer-fd:%{public}d", gettid(), timerId, interval, timerFd);
853         return TIMER_ERR_DEAL_FAILED;
854     }
855 
856     return timerId;
857 }
858 
CancelTimer(TimerHandlerPtr target)859 ErrCode Timer::CancelTimer(TimerHandlerPtr target)
860 {
861     BENCHMARK_LOGD("EventTest ErrCode Timer::CancelTimer is called.");
862     BENCHMARK_LOGD("||%{public}d||Cancle timer handler with fd:%{public}d", gettid(), target->GetTimerFd());
863     target->Uninitialize();
864     if (!target->Stop(reactor_.get())) {
865         BENCHMARK_LOGD("||%{public}d||Stop timer handler failed.", gettid());
866         return TIMER_ERR_DEAL_FAILED;
867     }
868 
869     timerHandlers_.erase(target->timerId_);
870 
871     auto handlerList = intervalToTimers_[target->interval_];
872     auto itor = std::find(handlerList.begin(), handlerList.end(), target);
873     if (itor != handlerList.end()) {
874         handlerList.erase(itor);
875     }
876 
877     if (handlerList.empty()) {
878         intervalToTimers_.erase(target->interval_);
879     }
880 
881     return TIMER_ERR_OK;
882 }
883 
Unregister(uint32_t timerId)884 void Timer::Unregister(uint32_t timerId)
885 {
886     BENCHMARK_LOGD("EventTest void Timer::Unregister is called.");
887     std::lock_guard<std::mutex> lock(mutex_);
888 
889     if (timerHandlers_.find(timerId) == timerHandlers_.end()) {
890         BENCHMARK_LOGD("||%{public}d||Unregister failed. timer-id:%{public}d not found.", gettid(), timerId);
891         return;
892     }
893 
894     auto entry = timerHandlers_[timerId];
895     BENCHMARK_LOGD("||%{public}d||Try remove timer handler from reactor. timerId:%{public}d, interval:%{public}u",
896         gettid(), timerId, entry->interval_);
897 
898     if (CancelTimer(entry) != TIMER_ERR_OK) {
899         BENCHMARK_LOGD("||%{public}d||Unregister timer handler failed.", gettid());
900     }
901 }
902 
OnTimer(TimerEventHandler * handler,const TimerCallback & callback)903 void Timer::OnTimer(TimerEventHandler* handler, const TimerCallback& callback)
904 {
905     BENCHMARK_LOGD("EventTest void Timer::OnTimer is called.");
906     callback();
907 
908     if (handler->once_) {
909         Unregister(handler->timerId_);
910     }
911 }
912 
GetValidId() const913 uint32_t Timer::GetValidId() const
914 {
915     BENCHMARK_LOGD("EventTest uint32_t Timer::GetValidId is called.");
916     static std::atomic_uint32_t timerId = 1;
917 
918     while (timerHandlers_.find(timerId) != timerHandlers_.end()) {
919         timerId++;
920         if (timerId == UINT32_MAX) {
921             timerId = 1;
922         }
923 
924         if (timerId == TIMER_ERR_DEAL_FAILED) {
925             timerId++;
926         }
927     }
928 
929     return timerId;
930 }
931 
GetTimerFd(uint32_t interval)932 int Timer::GetTimerFd(uint32_t interval /* ms */)
933 {
934     BENCHMARK_LOGD("EventTest int Timer::GetTimerFd is called.");
935     if (intervalToTimers_.find(interval) == intervalToTimers_.end()) {
936         return IO_EVENT_INVALID_FD;
937     }
938     auto &handlerList = intervalToTimers_[interval];
939     for (const TimerHandlerPtr &ptr : handlerList) {
940         if (!ptr->once_) {
941             return ptr->GetTimerFd();
942         }
943     }
944     return IO_EVENT_INVALID_FD;
945 }
946 
TimerEventHandler(int timerFd,uint32_t timeout,bool once)947 TimerEventHandler::TimerEventHandler(int timerFd, uint32_t timeout /* ms */, bool once)
948     : once_(once), interval_(timeout)
949 {
950     BENCHMARK_LOGD("EventTest     : once_(once), interval_ is called.");
951     if (timerFd == IO_EVENT_INVALID_FD) {
952         handler_ = std::make_unique<IOEventHandler>(timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC));
953     } else {
954         handler_ = std::make_unique<IOEventHandler>(timerFd);
955     }
956 }
957 
~TimerEventHandler()958 TimerEventHandler::~TimerEventHandler()
959 {
960     BENCHMARK_LOGD("EventTest TimerEventHandler::~TimerEventHandler is called.");
961     if (close(handler_->GetFd()) != 0) {
962         BENCHMARK_LOGD("||%{public}d||Close timer-fd failed. fd:%{public}d, interval:%{public}u, once:%{public}d",
963             gettid(), handler_->GetFd(), interval_, once_);
964     }
965     handler_->SetFd(IO_EVENT_INVALID_FD);
966 }
967 
Initialize()968 ErrCode TimerEventHandler::Initialize()
969 {
970     BENCHMARK_LOGD("EventTest ErrCode TimerEventHandler::Initialize is called.");
971     if (handler_->GetFd() == IO_EVENT_INVALID_FD) {
972         BENCHMARK_LOGD("||%{public}d||Invalid timer-fd:%{public}d, interval:%{public}u, once:%{public}d",
973             gettid(), handler_->GetFd(), interval_, once_);
974         return TIMER_ERR_INVALID_VALUE;
975     }
976 
977     struct itimerspec newValue = {{0, 0}, {0, 0}};
978     timespec now{0, 0};
979     if (clock_gettime(CLOCK_MONOTONIC, &now) == INVALID_FD) {
980         BENCHMARK_LOGD("||%{public}d||Get current time failed.", gettid());
981         return TIMER_ERR_DEAL_FAILED;
982     }
983 
984     // next time out time is now + interval
985     newValue.it_value.tv_sec = now.tv_sec + interval_ / MILLI_TO_BASE;
986     newValue.it_value.tv_nsec = now.tv_nsec + (interval_ % MILLI_TO_BASE) * MILLI_TO_NANO;
987     if (newValue.it_value.tv_nsec >= NANO_TO_BASE) {
988         newValue.it_value.tv_sec += 1;
989         newValue.it_value.tv_nsec = newValue.it_value.tv_nsec % NANO_TO_BASE;
990     }
991 
992     if (once_) {
993         // interval, 0 means time out only once
994         newValue.it_interval.tv_sec  = 0;
995         newValue.it_interval.tv_nsec = 0;
996     } else {
997         // interval
998         newValue.it_interval.tv_sec  = interval_ / MILLI_TO_BASE;
999         newValue.it_interval.tv_nsec = (interval_ % MILLI_TO_BASE) * MILLI_TO_NANO;
1000     }
1001 
1002     if (timerfd_settime(handler_->GetFd(), TFD_TIMER_ABSTIME, &newValue, nullptr) == INVALID_FD) {
1003         BENCHMARK_LOGD("||%{public}d||Set timer-fd failed. next:%{public}lld, interval:%{public}lld",
1004             gettid(), static_cast<long long>(newValue.it_value.tv_sec),
1005             static_cast<long long>(newValue.it_interval.tv_sec));
1006 
1007         return TIMER_ERR_DEAL_FAILED;
1008     }
1009 
1010     handler_->SetCallback(std::bind(&TimerEventHandler::TimeOut, this));
1011     handler_->EnableRead();
1012 
1013     return TIMER_ERR_OK;
1014 }
1015 
Uninitialize()1016 void TimerEventHandler::Uninitialize()
1017 {
1018     BENCHMARK_LOGD("EventTest void TimerEventHandler::Uninitialize is called.");
1019     handler_->DisableAll();
1020 }
1021 
Start(IOEventReactor * reactor)1022 bool TimerEventHandler::Start(IOEventReactor* reactor)
1023 {
1024     BENCHMARK_LOGD("EventTest bool TimerEventHandler::Start is called.");
1025     if (handler_ == nullptr || !handler_->Start(reactor)) {
1026         return false;
1027     }
1028 
1029     return true;
1030 }
1031 
Stop(IOEventReactor * reactor)1032 bool TimerEventHandler::Stop(IOEventReactor* reactor)
1033 {
1034     BENCHMARK_LOGD("EventTest bool TimerEventHandler::Stop is called.");
1035     if (handler_ == nullptr || !handler_->Stop(reactor)) {
1036         return false;
1037     }
1038 
1039     return true;
1040 }
1041 
TimeOut()1042 void TimerEventHandler::TimeOut()
1043 {
1044     if (handler_->GetFd() == IO_EVENT_INVALID_FD) {
1045         BENCHMARK_LOGD("||%{public}d||Invalid timerfd.", gettid());
1046         return;
1047     }
1048     uint64_t expirations = 0;
1049     const size_t expirationSize = sizeof(expirations);
1050     ssize_t n = ::read(handler_->GetFd(), &expirations, expirationSize);
1051     if (n != expirationSize) {
1052         BENCHMARK_LOGD("||%{public}d||Reads %{public}d bytes instead of %{public}zu from timer fd.",
1053             gettid(), static_cast<int>(n), expirationSize);
1054     }
1055 
1056     if (timerEventCallback_) {
1057         timerEventCallback_(this);
1058     }
1059 }
1060 
1061 
CurMs()1062 int64_t CurMs()
1063 {
1064     struct timeval tpend;
1065     gettimeofday(&tpend, nullptr);
1066     return (tpend.tv_sec * 1000000 + tpend.tv_usec) / 1000; // 1000000: s to us, 1000: us to ms
1067 }
1068 
1069 std::atomic<int> g_data1(0);
TimeOutCallback1()1070 void TimeOutCallback1()
1071 {
1072     g_data1 = g_data1 + 1;
1073 }
1074 
1075 std::atomic<int> g_data2(0);
TimeOutCallback2()1076 void TimeOutCallback2()
1077 {
1078     g_data2 += 1;
1079 }
1080 
1081 /*
1082  * @tc.name: testNewTimer001
1083  * @tc.desc: test basic function of timer implemented by new event-system.
1084  */
BENCHMARK_F(BenchmarkEventTest,testNewTimer001)1085 BENCHMARK_F(BenchmarkEventTest, testNewTimer001)(benchmark::State& state)
1086 {
1087     BENCHMARK_LOGD("EventTest testNewTimer001 start.");
1088     const int sleepDurationMs = 15;
1089     while (state.KeepRunning()) {
1090         g_data1 = 0;
1091         Timer timer("test_timer", 100);
1092         uint32_t ret = timer.Setup();
1093         AssertEqual(Utils::TIMER_ERR_OK, ret, "Utils::TIMER_ERR_OK did not equal ret as expected.", state);
1094         timer.Register(TimeOutCallback1, 1, true);
1095         std::this_thread::sleep_for(std::chrono::milliseconds(sleepDurationMs));
1096         timer.Shutdown();
1097         AssertEqual(1, g_data1, "1 did not equal g_data1 as expected.", state);
1098     }
1099     BENCHMARK_LOGD("EventTest testNewTimer001 end.");
1100 }
1101 
1102 /*
1103  * @tc.name: testNewTimer002
1104  * @tc.desc: test basic function of timer implemented by new event-system.
1105  */
BENCHMARK_F(BenchmarkEventTest,testNewTimer002)1106 BENCHMARK_F(BenchmarkEventTest, testNewTimer002)(benchmark::State& state)
1107 {
1108     BENCHMARK_LOGD("EventTest testNewTimer002 start.");
1109     constexpr uint32_t sleepDurationMs = 200;
1110     constexpr int expectedData1 = 8;
1111     constexpr int expectedData2 = 2;
1112     while (state.KeepRunning()) {
1113         g_data1 = 0;
1114         g_data2 = 0;
1115         Timer timer("test_timer", 50);
1116         uint32_t ret = timer.Setup();
1117         AssertEqual(Utils::TIMER_ERR_OK, ret, "Utils::TIMER_ERR_OK did not equal ret as expected.", state);
1118         timer.Register(TimeOutCallback1, TIMEOUT_ONE_MS);
1119         timer.Register(TimeOutCallback2, TIMEOUT_TWO_MS);
1120         std::this_thread::sleep_for(std::chrono::milliseconds(sleepDurationMs));
1121         timer.Shutdown();
1122         AssertGreaterThanOrEqual(g_data1, expectedData1,
1123             "g_data1 was not greater than or equal to expectedData1 as expected.", state);
1124         AssertGreaterThanOrEqual(g_data2, expectedData2,
1125             "g_data2 was not greater than or equal to expectedData2 as expected.", state);
1126     }
1127     BENCHMARK_LOGD("EventTest testNewTimer002 end.");
1128 }
1129 
1130 /*
1131  * @tc.name: testNewTimer003
1132  * @tc.desc: test basic function of timer implemented by new event-system.
1133  */
BENCHMARK_F(BenchmarkEventTest,testNewTimer003)1134 BENCHMARK_F(BenchmarkEventTest, testNewTimer003)(benchmark::State& state)
1135 {
1136     BENCHMARK_LOGD("EventTest testNewTimer003 start.");
1137     constexpr uint32_t sleepDurationMs = 30;
1138     constexpr int expectedData = 5;
1139     while (state.KeepRunning()) {
1140         g_data1 = 0;
1141         Timer timer("test_timer", 100);
1142         uint32_t ret = timer.Setup();
1143         AssertEqual(Utils::TIMER_ERR_OK, ret, "Utils::TIMER_ERR_OK did not equal ret as expected.", state);
1144         timer.Register(TimeOutCallback1, TIMEOUT_ONE_MS);
1145         timer.Register(TimeOutCallback1, TIMEOUT_TWO_MS);
1146         std::this_thread::sleep_for(std::chrono::milliseconds(sleepDurationMs));
1147         timer.Shutdown();
1148         AssertGreaterThanOrEqual(g_data1, expectedData,
1149             "g_data1 was not greater than or equal to expectedData as expected.", state);
1150     }
1151     BENCHMARK_LOGD("EventTest testNewTimer003 end.");
1152 }
1153 
1154 class A {
1155 public:
A(int data)1156     explicit A(int data) : data_(data), timer_("ATimer", 100) {}
1157     ~A() = default;
1158     bool Init();
1159     bool StartTimer(int milliseconds, bool once);
1160     void StopTimer();
GetData() const1161     int GetData() const {return data_;}
1162 private:
TimeOutProc()1163     void TimeOutProc()
1164     {
1165         data_ = data_ - 1;
1166     };
1167     int data_;
1168     Timer timer_;
1169 };
1170 
Init()1171 bool A::Init()
1172 {
1173     BENCHMARK_LOGD("EventTest bool A::Init is called.");
1174     return timer_.Setup() == Utils::TIMER_ERR_OK;
1175 }
1176 
StartTimer(int milliseconds,bool once)1177 bool A::StartTimer(int milliseconds, bool once)
1178 {
1179     BENCHMARK_LOGD("EventTest bool A::StartTimer is called.");
1180     uint32_t timerId = timer_.Register(std::bind(&A::TimeOutProc, this), milliseconds, once);
1181     return timerId != Utils::TIMER_ERR_DEAL_FAILED;
1182 }
1183 
StopTimer()1184 void A::StopTimer()
1185 {
1186     BENCHMARK_LOGD("EventTest void A::StopTimer is called.");
1187     timer_.Shutdown();
1188 }
1189 
1190 /*
1191  * @tc.name: testNewTimer004
1192  * @tc.desc: test wrapper of the timer implemented by new event-system.
1193  */
BENCHMARK_F(BenchmarkEventTest,testNewTimer004)1194 BENCHMARK_F(BenchmarkEventTest, testNewTimer004)(benchmark::State& state)
1195 {
1196     BENCHMARK_LOGD("EventTest testNewTimer004 start.");
1197     constexpr int initialValue = 10;
1198     constexpr int timeoutSeconds = 1;
1199     constexpr int sleepDurationMs = 20;
1200     constexpr int expectedData = 9;
1201     while (state.KeepRunning()) {
1202         A a(initialValue);
1203         AssertTrue((a.Init()), "a.Init() did not equal true as expected.", state);
1204         AssertTrue((a.StartTimer(timeoutSeconds, true)),
1205             "a.StartTimer(timeoutSeconds, true) did not equal true as expected.", state);
1206         std::this_thread::sleep_for(std::chrono::milliseconds(sleepDurationMs));
1207         a.StopTimer();
1208         AssertEqual(expectedData, a.GetData(), "expectedData did not equal a.GetData() as expected.", state);
1209     }
1210     BENCHMARK_LOGD("EventTest testNewTimer004 end.");
1211 }
1212 
1213 /*
1214  * @tc.name: testNewTimer005
1215  * @tc.desc: test abnormal case of timer implemented by new event-system.
1216  */
BENCHMARK_F(BenchmarkEventTest,testNewTimer005)1217 BENCHMARK_F(BenchmarkEventTest, testNewTimer005)(benchmark::State& state)
1218 {
1219     BENCHMARK_LOGD("EventTest testNewTimer005 start.");
1220     constexpr uint32_t loopCount = 10;
1221     constexpr uint32_t timeoutSeconds = 7;
1222     constexpr uint32_t sleepDurationMs = 10;
1223     constexpr int expectedData = 5;
1224     while (state.KeepRunning()) {
1225         g_data1 = 0;
1226         Timer timer("test_timer", INVALID_FD);
1227         uint32_t ret = timer.Setup();
1228         AssertEqual(Utils::TIMER_ERR_OK, ret, "Utils::TIMER_ERR_OK did not equal ret as expected.", state);
1229 
1230         uint32_t timerId = 0;
1231         for (uint32_t i = 0; i < loopCount; i++) {
1232             timerId = timer.Register(TimeOutCallback1, timeoutSeconds, true);
1233             std::this_thread::sleep_for(std::chrono::milliseconds(sleepDurationMs));
1234         }
1235         timer.Unregister(timerId);
1236         timer.Unregister(timerId);
1237 
1238         timer.Shutdown();
1239         timer.Shutdown(false);
1240         AssertGreaterThanOrEqual(g_data1, expectedData,
1241             "g_data1 was not greater than or equal to expectedData as expected.", state);
1242     }
1243     BENCHMARK_LOGD("EventTest testNewTimer005 end.");
1244 }
1245 
BENCHMARK_F(BenchmarkEventTest,testNewTimer006)1246 BENCHMARK_F(BenchmarkEventTest, testNewTimer006)(benchmark::State& state)
1247 {
1248     BENCHMARK_LOGD("EventTest testNewTimer006 start.");
1249     constexpr uint32_t timeoutSeconds = 10;
1250     constexpr int loopCount = 11;
1251     constexpr int sleepDurationMs = 10;
1252     constexpr int expectedTimeDiff = 10;
1253     constexpr int expectedData = 10;
1254     while (state.KeepRunning()) {
1255         g_data1 = 0;
1256         Timer timer("test_timer", 100);
1257         uint32_t ret = timer.Setup();
1258         AssertEqual(Utils::TIMER_ERR_OK, ret, "Utils::TIMER_ERR_OK did not equal ret as expected.", state);
1259         timer.Register(TimeOutCallback1, timeoutSeconds);
1260 
1261         for (int i = 0; i < loopCount; i++) {
1262             int64_t pre = CurMs();
1263             std::this_thread::sleep_for(std::chrono::milliseconds(sleepDurationMs));
1264             int64_t cur = CurMs();
1265             AssertGreaterThanOrEqual(cur - pre, expectedTimeDiff,
1266                 "cur - pre was not greater than or equal to expectedTimeDiff as expected.", state);
1267         }
1268         timer.Shutdown();
1269         AssertGreaterThanOrEqual(g_data1, expectedData,
1270             "g_data1 was not greater than or equal to expectedData as expected.", state);
1271     }
1272     BENCHMARK_LOGD("EventTest testNewTimer006 end.");
1273 }
1274 
1275 constexpr int RECURSION_DEPTH = 9;
1276 constexpr int INTERVAL_SECONDS = 10;
1277 
1278 /*
1279  * @tc.name: testNewTimer007
1280  * @tc.desc: recursive test of timer implemented by new event-system.
1281  */
DoFunc(Timer & timer,int & count)1282 void DoFunc(Timer &timer, int &count)
1283 {
1284     BENCHMARK_LOGD("EventTest void DoFunc is called.");
1285     (void)timer.Register(
1286         [&timer, &count]() {
1287             count += 1;
1288             if (count > RECURSION_DEPTH) {
1289                 return;
1290             }
1291             DoFunc(timer, count);
1292         },
1293         INTERVAL_SECONDS, true);
1294     g_data1++;
1295 }
1296 
DoFunc2(Timer & timer,int & count)1297 void DoFunc2(Timer &timer, int &count)
1298 {
1299     BENCHMARK_LOGD("EventTest void DoFunc2 is called.");
1300     (void)timer.Register(
1301         [&timer, &count]() {
1302             count += 1;
1303             if (count > RECURSION_DEPTH) {
1304                 return;
1305             }
1306             DoFunc2(timer, count);
1307         },
1308         INTERVAL_SECONDS, true);
1309     g_data1++;
1310 }
1311 
BENCHMARK_F(BenchmarkEventTest,testNewTimer007)1312 BENCHMARK_F(BenchmarkEventTest, testNewTimer007)(benchmark::State& state)
1313 {
1314     BENCHMARK_LOGD("EventTest testNewTimer007 start.");
1315     constexpr int expectedMinData = 5;
1316     constexpr int expectedMaxData = 14;
1317     constexpr int expectedMinDataAfterShutdown = 10;
1318     constexpr int sleepDurationMs = 50;
1319     while (state.KeepRunning()) {
1320         g_data1 = 0;
1321         Timer timer("test_timer", 100);
1322         uint32_t ret = timer.Setup();
1323         AssertEqual(Utils::TIMER_ERR_OK, ret, "Utils::TIMER_ERR_OK did not equal ret as expected.", state);
1324 
1325         int cnt = 0, cnt1 = 0;
1326         DoFunc(timer, cnt);
1327         DoFunc2(timer, cnt1);
1328         std::this_thread::sleep_for(std::chrono::milliseconds(sleepDurationMs));
1329         AssertGreaterThanOrEqual(g_data1, expectedMinData,
1330             "g_data1 was not greater than or equal to expectedMinData as expected.", state);
1331         AssertGreaterThanOrEqual(expectedMaxData, g_data1,
1332             "expectedMaxData was not greater than or equal to g_data1 as expected.", state);
1333         std::this_thread::sleep_for(std::chrono::milliseconds(sleepDurationMs));
1334         timer.Shutdown();
1335         AssertGreaterThanOrEqual(g_data1, expectedMinDataAfterShutdown,
1336             "g_data1 was not greater than or equal to expectedMinDataAfterShutdown as expected.", state);
1337     }
1338     BENCHMARK_LOGD("EventTest testNewTimer007 end.");
1339 }
1340 
1341 /*
1342  * @tc.name: testNewTimer008
1343  * @tc.desc: test execute-once and execute-periodly tasks.
1344  */
BENCHMARK_F(BenchmarkEventTest,testNewTimer008)1345 BENCHMARK_F(BenchmarkEventTest, testNewTimer008)(benchmark::State& state)
1346 {
1347     BENCHMARK_LOGD("EventTest testNewTimer008 start.");
1348     constexpr int intervalSeconds = 10;
1349     constexpr int sleepDurationMs = 52;
1350     constexpr int expectedMinData = 8;
1351     while (state.KeepRunning()) {
1352         g_data1 = 0;
1353         Timer timer("test_timer", 100);
1354         uint32_t ret = timer.Setup();
1355         AssertEqual(Utils::TIMER_ERR_OK, ret, "Utils::TIMER_ERR_OK did not equal ret as expected.", state);
1356         timer.Register(TimeOutCallback1, intervalSeconds, true);
1357         timer.Register(TimeOutCallback1, intervalSeconds);
1358         timer.Register(TimeOutCallback1, intervalSeconds, true);
1359         timer.Register(TimeOutCallback1, intervalSeconds);
1360         std::this_thread::sleep_for(std::chrono::milliseconds(sleepDurationMs));
1361         timer.Shutdown();
1362         AssertGreaterThanOrEqual(g_data1, expectedMinData,
1363             "g_data1 was not greater than or equal to expectedMinData as expected.", state);
1364     }
1365     BENCHMARK_LOGD("EventTest testNewTimer008 end.");
1366 }
1367 
1368 /*
1369  * @tc.name: testIOEventHandlerConstruction001
1370  * @tc.desc: test construction of IOEventHandler.
1371  */
BENCHMARK_F(BenchmarkEventTest,testIOEventHandlerConstruction001)1372 BENCHMARK_F(BenchmarkEventTest, testIOEventHandlerConstruction001)(benchmark::State& state)
1373 {
1374     BENCHMARK_LOGD("EventTest testIOEventHandlerConstruction001 start.");
1375     while (state.KeepRunning()) {
1376         // 1. Construct IOEventHandler
1377         std::shared_ptr<IOEventHandler> handler = std::make_shared<IOEventHandler>();
1378 
1379         // 2. Check initialization
1380         AssertEqual(handler->GetFd(), IO_EVENT_INVALID_FD,
1381             "handler->GetFd() did not equal IO_EVENT_INVALID_FD as expected.", state);
1382         AssertEqual(handler->GetEvents(), Events::EVENT_NONE,
1383             "handler->GetEvents() did not equal Events::EVENT_NONE as expected.", state);
1384         AssertEqual(handler->GetCallback(), nullptr,
1385             "handler->GetCallback() was not equal to nullptr as expected.", state);
1386         AssertEqual(handler->Prev(), nullptr, "handler->Prev() was not equal to nullptr as expected.", state);
1387         AssertEqual(handler->Next(), nullptr, "handler->Next() was not equal to nullptr as expected.", state);
1388         AssertEqual(handler->IsActive(), false, "handler->IsActive() was not equal to false as expected.", state);
1389     }
1390     BENCHMARK_LOGD("EventTest testIOEventHandlerConstruction001 end.");
1391 }
1392 
1393 /*
1394  * @tc.name: testIOEventHandlerConstructionWithParameters001
1395  * @tc.desc: test construction of IOEventHandler with parameters.
1396  */
BENCHMARK_F(BenchmarkEventTest,testIOEventHandlerConstructionWithParameters001)1397 BENCHMARK_F(BenchmarkEventTest, testIOEventHandlerConstructionWithParameters001)(benchmark::State& state)
1398 {
1399     BENCHMARK_LOGD("EventTest testIOEventHandlerConstructionWithParameters001 start.");
1400     while (state.KeepRunning()) {
1401         // 1. Define file descriptor and events
1402         int fd = 10;
1403         EventId events = Events::EVENT_READ;
1404 
1405         // 2. Construct IOEventHandler with parameters
1406         std::shared_ptr<IOEventHandler> handler = std::make_shared<IOEventHandler>(fd, events);
1407 
1408         // 3. Check initialization
1409         AssertEqual(handler->GetFd(), fd, "handler->GetFd() did not equal fd as expected.", state);
1410         AssertEqual(handler->GetEvents(), events, "handler->GetEvents() did not equal events as expected.", state);
1411         AssertEqual(handler->Prev(), nullptr, "handler->Prev() was not equal to nullptr as expected.", state);
1412         AssertEqual(handler->Next(), nullptr, "handler->Next() was not equal to nullptr as expected.", state);
1413         AssertEqual(handler->IsActive(), false, "handler->IsActive() was not equal to false as expected.", state);
1414     }
1415     BENCHMARK_LOGD("EventTest testIOEventHandlerConstructionWithParameters001 end.");
1416 }
1417 
1418 /*
1419  * @tc.name: testIOEventHandlerConstructor001
1420  * @tc.desc: test construction of IOEventHandler.
1421  */
BENCHMARK_F(BenchmarkEventTest,testIOEventHandlerConstructor001)1422 BENCHMARK_F(BenchmarkEventTest, testIOEventHandlerConstructor001)(benchmark::State& state)
1423 {
1424     BENCHMARK_LOGD("EventTest testIOEventHandlerConstructor001 start.");
1425     while (state.KeepRunning()) {
1426         // 1. Define file descriptor and events
1427         int fd = 10;
1428         EventId events = Events::EVENT_READ;
1429 
1430         // 2. Construct IOEventHandler with parameters and measure the time
1431         std::shared_ptr<IOEventHandler> handler = std::make_shared<IOEventHandler>(fd, events);
1432 
1433         // 3. Check if the handler is constructed correctly
1434         AssertEqual(handler->GetFd(), fd, "handler->GetFd() did not equal fd as expected.", state);
1435         AssertEqual(handler->GetEvents(), events, "handler->GetEvents() did not equal events as expected.", state);
1436     }
1437     BENCHMARK_LOGD("EventTest testIOEventHandlerConstructor001 end.");
1438 }
1439 }  // namespace
1440 }  // namespace OHOS
1441 // Run the benchmark
1442 BENCHMARK_MAIN();
1443