Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / ot-br-posix / repo / tests / unit / test_task_runner.cpp
1 /*
2  *    Copyright (c) 2021, The OpenThread Authors.
3  *    All rights reserved.
4  *
5  *    Redistribution and use in source and binary forms, with or without
6  *    modification, are permitted provided that the following conditions are met:
7  *    1. Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *    2. Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *    3. Neither the name of the copyright holder nor the
13  *       names of its contributors may be used to endorse or promote products
14  *       derived from this software without specific prior written permission.
15  *
16  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *    POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "common/task_runner.hpp"
30
31 #include <atomic>
32 #include <mutex>
33 #include <thread>
34
35 #include <CppUTest/TestHarness.h>
36
37 TEST_GROUP(TaskRunner){};
38
39 TEST(TaskRunner, TestSingleThread)
40 {
41     int                  rval;
42     int                  counter = 0;
43     otSysMainloopContext mainloop;
44     otbr::TaskRunner     taskRunner;
45
46     mainloop.mMaxFd   = -1;
47     mainloop.mTimeout = {10, 0};
48
49     FD_ZERO(&mainloop.mReadFdSet);
50     FD_ZERO(&mainloop.mWriteFdSet);
51     FD_ZERO(&mainloop.mErrorFdSet);
52
53     // Increase the `counter` to 3.
54     taskRunner.Post([&]() {
55         ++counter;
56         taskRunner.Post([&]() {
57             ++counter;
58             taskRunner.Post([&]() { ++counter; });
59         });
60     });
61
62     taskRunner.UpdateFdSet(mainloop);
63     rval = select(mainloop.mMaxFd + 1, &mainloop.mReadFdSet, &mainloop.mWriteFdSet, &mainloop.mErrorFdSet,
64                   &mainloop.mTimeout);
65     CHECK_EQUAL(1, rval);
66
67     taskRunner.Process(mainloop);
68     CHECK_EQUAL(3, counter);
69 }
70
71 TEST(TaskRunner, TestMultipleThreads)
72 {
73     std::atomic<int>         counter{0};
74     otbr::TaskRunner         taskRunner;
75     std::vector<std::thread> threads;
76
77     // Increase the `counter` to 10 in separate threads.
78     for (size_t i = 0; i < 10; ++i)
79     {
80         threads.emplace_back([&]() { taskRunner.Post([&]() { ++counter; }); });
81     }
82
83     while (counter.load() < 10)
84     {
85         int                  rval;
86         otSysMainloopContext mainloop;
87
88         mainloop.mMaxFd   = -1;
89         mainloop.mTimeout = {10, 0};
90
91         FD_ZERO(&mainloop.mReadFdSet);
92         FD_ZERO(&mainloop.mWriteFdSet);
93         FD_ZERO(&mainloop.mErrorFdSet);
94
95         taskRunner.UpdateFdSet(mainloop);
96         rval = select(mainloop.mMaxFd + 1, &mainloop.mReadFdSet, &mainloop.mWriteFdSet, &mainloop.mErrorFdSet,
97                       &mainloop.mTimeout);
98         CHECK_EQUAL(1, rval);
99
100         taskRunner.Process(mainloop);
101     }
102
103     for (auto &th : threads)
104     {
105         th.join();
106     }
107
108     CHECK_EQUAL(10, counter.load());
109 }
110
111 TEST(TaskRunner, TestPostAndWait)
112 {
113     std::atomic<int>         total{0};
114     std::atomic<int>         counter{0};
115     otbr::TaskRunner         taskRunner;
116     std::vector<std::thread> threads;
117
118     // Increase the `counter` to 10 in separate threads and accumulate the total value.
119     for (size_t i = 0; i < 10; ++i)
120     {
121         threads.emplace_back([&]() { total += taskRunner.PostAndWait<int>([&]() { return ++counter; }); });
122     }
123
124     while (counter.load() < 10)
125     {
126         int                  rval;
127         otSysMainloopContext mainloop;
128
129         mainloop.mMaxFd   = -1;
130         mainloop.mTimeout = {10, 0};
131
132         FD_ZERO(&mainloop.mReadFdSet);
133         FD_ZERO(&mainloop.mWriteFdSet);
134         FD_ZERO(&mainloop.mErrorFdSet);
135
136         taskRunner.UpdateFdSet(mainloop);
137         rval = select(mainloop.mMaxFd + 1, &mainloop.mReadFdSet, &mainloop.mWriteFdSet, &mainloop.mErrorFdSet,
138                       &mainloop.mTimeout);
139         CHECK_EQUAL(1, rval);
140
141         taskRunner.Process(mainloop);
142     }
143
144     for (auto &th : threads)
145     {
146         th.join();
147     }
148
149     CHECK_EQUAL(55, total);
150     CHECK_EQUAL(10, counter.load());
151 }