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 <thread>
17 #include <chrono>
18 #include <gtest/gtest.h>
19 #include "ffrt_inner.h"
20 #include "c/loop.h"
21 #define private public
22 #include "sync/poller.h"
23 #undef private
24 #include "util.h"
25 #include "../common.h"
26
27 using namespace std;
28 using namespace ffrt;
29 using namespace testing;
30 #ifdef HWTEST_TESTING_EXT_ENABLE
31 using namespace testing::ext;
32 #endif
33
34 class PollerTest : public testing::Test {
35 protected:
SetUpTestCase()36 static void SetUpTestCase()
37 {
38 }
39
TearDownTestCase()40 static void TearDownTestCase()
41 {
42 }
43
SetUp()44 void SetUp() override
45 {
46 }
47
TearDown()48 void TearDown() override
49 {
50 }
51 };
52
Testfun(void * data)53 static void Testfun(void* data)
54 {
55 int* testData = static_cast<int*>(data);
56 *testData += 1;
57 printf("%d, timeout callback\n", *testData);
58 }
59 static void (*g_cb)(void*) = Testfun;
60
61 /*
62 * 测试用例名称:poll_once_batch_timeout
63 * 测试用例描述:PollOnce批量超时测试
64 * 预置条件 :无
65 * 操作步骤 :1、调用注册接口
66 2、单次调用PollOnce
67 * 预期结果 :1、超时任务全部从队列中清除
68 2、当实际超时时间很长,但是传入超时时间很短,应该按传入时间执行
69 */
70 HWTEST_F(PollerTest, poll_once_batch_timeout, TestSize.Level1)
71 {
72 Poller poller;
73 // 1、组装timeMap_
74 static int result0 = 0;
75 int* xf = &result0;
76 void* data = xf;
77 uint64_t timeout = 10;
78 uint64_t timeout1 = 11;
79 uint64_t timeout2 = 12;
80 uint64_t sleepTime = 25000;
81 poller.RegisterTimer(timeout, data, g_cb, false);
82 poller.RegisterTimer(timeout1, data, g_cb, false);
83 poller.RegisterTimer(timeout2, data, g_cb, false);
84 // 调用PollOnce,预计timerMap_为空,全部清除
85 usleep(sleepTime);
86 poller.PollOnce(1);
87 EXPECT_EQ(true, poller.DetermineEmptyMap());
88
89 uint64_t timeout3 = 10000;
90 uint64_t timeout4 = 100;
91 int loopNum = 2;
92 poller.RegisterTimer(timeout3, data, g_cb, false);
93 TimePoint start = std::chrono::steady_clock::now();
94 for (int i = 0; i < loopNum; ++i) {
95 poller.PollOnce(timeout4);
96 }
97 TimePoint end = std::chrono::steady_clock::now();
98 int m = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
99 // 预计等待时间为100,可能有几毫秒的误差
100 EXPECT_EQ(true, m >= timeout4 && m < timeout3);
101 }
102
103 /*
104 * 测试用例名称:poll_once_batch_timeout
105 * 测试用例描述:PollOnce批量超时测试
106 * 预置条件 :无
107 * 操作步骤 :1、调用注册接口,注册repeat为true的timer
108 2、创建两个线程,并发PollerOnce和Unregister
109 * 预期结果 :1、任务全部从队列中清除
110 */
111 HWTEST_F(PollerTest, unregister_timer_001, TestSize.Level1)
112 {
113 Poller poller;
114 // 1、组装timeMap_
115 static int result0 = 0;
116 int* xf = &result0;
117 void* data = xf;
118 uint64_t timeout = 1;
119 uint64_t sleepTime = 2500;
120 int maxIter = 100;
121 // 2、 创建两个线程,并发PollerOnce和Unregister
122 for (int i = 0; i < maxIter; i++) {
123 int timerHandle = poller.RegisterTimer(timeout, data, g_cb, true);
124 EXPECT_FALSE(poller.timerMap_.empty());
125 auto boundPollonce = std::bind(&Poller::PollOnce, &poller, timeout);
126 auto boundUnregister = std::bind(&Poller::UnregisterTimer, &poller, timerHandle);
127 usleep(sleepTime);
128 std::thread thread1(boundPollonce);
129 std::thread thread2(boundUnregister);
130 thread1.join();
131 thread2.join();
132 EXPECT_TRUE(poller.timerMap_.empty());
133 EXPECT_TRUE(poller.executedHandle_.empty());
134 poller.timerMap_.clear();
135 poller.executedHandle_.clear();
136 }
137 }
138
139 std::mutex g_mutexRegister;
140 std::condition_variable g_cvRegister;
141
WaitCallback(void * data)142 void WaitCallback(void* data)
143 {
144 int* dependency = reinterpret_cast<int*>(data);
145 while (*dependency != 1) {
146 std::this_thread::yield();
147 }
148 }
149
EmptyCallback(void * data)150 void EmptyCallback(void* data) {}
151
152 /*
153 * 测试用例名称:multi_timer_dependency
154 * 测试用例描述:poller批量超时回调依赖测试
155 * 预置条件 :构造三个超时时间相同的timer,回调A依赖回调B执行完成,回调B依赖timer C取消成功,三者并发
156 * 操作步骤 :1、调用PollOnce接口
157 * 预期结果 :1、三个回调执行完成,没有卡死现象
158 */
159 HWTEST_F(PollerTest, multi_timer_dependency, TestSize.Level1)
160 {
161 int dependency = 0;
__anon52d4ac2d0102null162 ffrt::task_handle handle = ffrt::submit_h([&] {
163 std::unique_lock lk(g_mutexRegister);
164 g_cvRegister.wait(lk);
165 dependency = 1;
166 });
167
168 TimePoint timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(100);
169 TimerDataWithCb data(&dependency, WaitCallback, nullptr, false, 100);
170 data.handle = 0;
171
172 Poller poller;
173 poller.timerMap_.emplace(timeout, data);
174
175 data.handle++;
176 data.cb = EmptyCallback;
177 poller.timerMap_.emplace(timeout, data);
178
__anon52d4ac2d0202null179 std::thread th1([&] { poller.PollOnce(-1); });
__anon52d4ac2d0302null180 std::thread th2([&] {
181 usleep(100 * 1000);
182 poller.UnregisterTimer(1);
183 g_cvRegister.notify_all();
184 });
185
186 th1.join();
187 th2.join();
188 ffrt::wait({handle});
189 }
190
191 /*
192 * 测试用例名称:multi_timer_dependency_unregister_self
193 * 测试用例描述:poller批量超时回调,解注册自身依赖测试
194 * 预置条件 :构造两个超时时间相同的timer,回调A依赖回调B执行完成,回调B依赖另一个线程的timer A取消成功,三者并发
195 * 操作步骤 :调用PollOnce接口
196 * 预期结果 :三个回调执行完成,没有卡死现象
197 */
198 HWTEST_F(PollerTest, multi_timer_dependency_unregister_self, TestSize.Level1)
199 {
200 int dependency = 0;
201
202 TimePoint timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(100);
203 TimerDataWithCb data(&dependency, WaitCallback, nullptr, false, 100);
204 data.handle = 0;
205
206 Poller poller;
207 poller.timerMap_.emplace(timeout, data);
208
209 data.handle++;
210 data.cb = EmptyCallback;
211 poller.timerMap_.emplace(timeout, data);
212
__anon52d4ac2d0402null213 ffrt::task_handle handle = ffrt::submit_h([&] {
214 std::unique_lock lk(g_mutexRegister);
215 g_cvRegister.wait(lk);
216 poller.IsTimerReady();
217 dependency = 1;
218 });
219
__anon52d4ac2d0502null220 std::thread th1([&] { poller.PollOnce(-1); });
__anon52d4ac2d0602null221 std::thread th2([&] {
222 usleep(100 * 1000);
223 g_cvRegister.notify_all();
224 poller.UnregisterTimer(0);
225 });
226
227 th1.join();
228 th2.join();
229 ffrt::wait({handle});
230 }
231
232 /*
233 * 测试用例名称 : fetch_cached_event_unmask DoTaskFdAdd
234 * 测试用例描述 : 遍历本地events缓存,并提出缓存event
235 * 预置条件 : 无
236 * 操作步骤 :
237 * 预期结果 :
238 */
239 HWTEST_F(PollerTest, TestCacheDelFd001, TestSize.Level1)
240 {
241 Poller poller;
242 CPUEUTask* currTask = static_cast<CPUEUTask*>(malloc(sizeof(CPUEUTask)));
243 int fd = 1001;
244 int fd1 = 1002;
245 poller.CacheDelFd(fd, currTask);
246 poller.CacheDelFd(fd1, currTask);
247 std::unique_ptr<struct WakeDataWithCb> maskWakeData = std::make_unique<WakeDataWithCb>(fd, nullptr,
248 nullptr, currTask);
249 std::unique_ptr<struct WakeDataWithCb> maskWakeData1 = std::make_unique<WakeDataWithCb>(fd1, nullptr,
250 nullptr, currTask);
251 poller.CacheMaskWakeData(currTask, maskWakeData);
252 poller.CacheMaskWakeData(currTask, maskWakeData1);
253
254 EXPECT_EQ(2, poller.m_delFdCacheMap.size());
255 EXPECT_EQ(1, poller.m_maskWakeDataWithCbMap.size());
256 EXPECT_EQ(2, poller.m_maskWakeDataWithCbMap[currTask].size());
257
258 poller.ClearMaskWakeDataWithCbCacheWithFd(currTask, fd);
259 EXPECT_EQ(2, poller.m_delFdCacheMap.size());
260 EXPECT_EQ(1, poller.m_maskWakeDataWithCbMap.size());
261 EXPECT_EQ(1, poller.m_maskWakeDataWithCbMap[currTask].size());
262
263 poller.ClearMaskWakeDataWithCbCacheWithFd(currTask, fd1);
264 EXPECT_EQ(2, poller.m_delFdCacheMap.size());
265 EXPECT_EQ(0, poller.m_maskWakeDataWithCbMap.size());
266 EXPECT_EQ(0, poller.m_maskWakeDataWithCbMap[currTask].size());
267
268 free(currTask);
269 }
270
271 /*
272 * 测试用例名称 : fetch_cached_event_unmask DoTaskFdAdd
273 * 测试用例描述 : 遍历本地events缓存,并提出缓存event
274 * 预置条件 : 无
275 * 操作步骤 :
276 * 预期结果 :
277 */
278 HWTEST_F(PollerTest, TestCacheDelFd002, TestSize.Level1)
279 {
280 Poller poller;
281 CPUEUTask* currTask = static_cast<CPUEUTask*>(malloc(sizeof(CPUEUTask)));
282 int fd = 1001;
283 int fd1 = 1002;
284 poller.m_delFdCacheMap.emplace(fd, currTask);
285 poller.m_delFdCacheMap.emplace(fd1, currTask);
286 std::unique_ptr<struct WakeDataWithCb> maskWakeData = std::make_unique<WakeDataWithCb>(fd, nullptr,
287 nullptr, currTask);
288 std::unique_ptr<struct WakeDataWithCb> maskWakeData1 = std::make_unique<WakeDataWithCb>(fd1, nullptr,
289 nullptr, currTask);
290 poller.m_maskWakeDataWithCbMap[currTask].emplace_back(std::move(maskWakeData));
291 poller.m_maskWakeDataWithCbMap[currTask].emplace_back(std::move(maskWakeData1));
292
293 EXPECT_EQ(2, poller.m_delFdCacheMap.size());
294 EXPECT_EQ(1, poller.m_maskWakeDataWithCbMap.size());
295 EXPECT_EQ(2, poller.m_maskWakeDataWithCbMap[currTask].size());
296
297 poller.ClearMaskWakeDataWithCbCache(currTask);
298
299 EXPECT_EQ(0, poller.m_delFdCacheMap.size());
300 EXPECT_EQ(0, poller.m_maskWakeDataWithCbMap.size());
301 EXPECT_EQ(0, poller.m_maskWakeDataWithCbMap[currTask].size());
302
303 free(currTask);
304 }
305
306 /*
307 * 测试用例名称 : fetch_cached_event_unmask DoTaskFdAdd
308 * 测试用例描述 : 遍历本地events缓存,并提出缓存event
309 * 预置条件 : 无
310 * 操作步骤 :
311 * 预期结果 :
312 */
313 HWTEST_F(PollerTest, TestCacheDelFd003, TestSize.Level1)
314 {
315 Poller poller;
316 CPUEUTask* currTask = static_cast<CPUEUTask*>(malloc(sizeof(CPUEUTask)));
317 int fd = 1001;
318 int fd1 = 1002;
319 poller.m_delFdCacheMap.emplace(fd, currTask);
320 poller.m_delFdCacheMap.emplace(fd1, currTask);
321 std::unique_ptr<struct WakeDataWithCb> maskWakeData = std::make_unique<WakeDataWithCb>(fd, nullptr,
322 nullptr, currTask);
323 std::unique_ptr<struct WakeDataWithCb> maskWakeData1 = std::make_unique<WakeDataWithCb>(fd1, nullptr,
324 nullptr, currTask);
325 poller.m_maskWakeDataWithCbMap[currTask].emplace_back(std::move(maskWakeData));
326 poller.m_maskWakeDataWithCbMap[currTask].emplace_back(std::move(maskWakeData1));
327
328 EXPECT_EQ(2, poller.m_delFdCacheMap.size());
329 EXPECT_EQ(1, poller.m_maskWakeDataWithCbMap.size());
330 EXPECT_EQ(2, poller.m_maskWakeDataWithCbMap[currTask].size());
331
332 poller.ClearDelFdCache(fd);
333 EXPECT_EQ(1, poller.m_delFdCacheMap.size());
334 EXPECT_EQ(1, poller.m_maskWakeDataWithCbMap.size());
335 EXPECT_EQ(1, poller.m_maskWakeDataWithCbMap[currTask].size());
336
337 poller.ClearDelFdCache(fd1);
338 EXPECT_EQ(0, poller.m_delFdCacheMap.size());
339 EXPECT_EQ(0, poller.m_maskWakeDataWithCbMap.size());
340 EXPECT_EQ(0, poller.m_maskWakeDataWithCbMap[currTask].size());
341
342 free(currTask);
343 }