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 <gtest/gtest.h>
17 #include <random>
18 #include <cinttypes>
19 #include "ffrt_inner.h"
20 #include "util.h"
21 #include "c/deadline.h"
22 #include "c/executor_task.h"
23 #include "tm/scpu_task.h"
24 #include "dfx/log/ffrt_log_api.h"
25 #define private public
26 #include "dm/sdependence_manager.h"
27 #include "sched/task_scheduler.h"
28 #undef private
29 #include "util/ffrt_facade.h"
30 #ifndef WITH_NO_MOCKER
31 extern "C" int ffrt_set_cgroup_attr(ffrt_qos_t qos, ffrt_os_sched_attr *attr);
32 #endif
33 #include "../common.h"
34
35 using namespace std;
36 using namespace testing;
37 #ifdef HWTEST_TESTING_EXT_ENABLE
38 using namespace testing::ext;
39 #endif
40
41 class DependencyTest : public testing::Test {
42 protected:
SetUpTestCase()43 static void SetUpTestCase()
44 {
45 }
46
TearDownTestCase()47 static void TearDownTestCase()
48 {
49 }
50
SetUp()51 void SetUp() override
52 {
53 }
54
TearDown()55 void TearDown() override
56 {
57 }
58 };
59
60 HWTEST_F(DependencyTest, dependency_success_01, TestSize.Level0)
61 {
62 int x = 0;
__anon014c45000302() 63 ffrt::submit([&]() { x = 2; }, {}, {&x});
__anon014c45000402() 64 ffrt::submit([&]() { x = x * 3; }, {&x}, {});
65 ffrt::wait();
66 EXPECT_EQ(x, 6);
67 }
68
69 HWTEST_F(DependencyTest, update_qos_success_02, TestSize.Level0)
70 {
71 int ret = ffrt_task_attr_init(nullptr);
72 EXPECT_EQ(ret, -1);
73 ffrt_task_attr_get_name(nullptr);
74 ffrt_task_attr_set_name(nullptr, "A");
75 ffrt_task_attr_set_qos(nullptr, static_cast<int>(ffrt::qos_user_initiated));
76 ffrt_task_attr_get_qos(nullptr);
77 ffrt_task_attr_destroy(nullptr);
78 ffrt_submit_base(nullptr, nullptr, nullptr, nullptr);
79 ffrt_submit_h_base(nullptr, nullptr, nullptr, nullptr);
__anon014c45000702null80 ffrt::submit([] {
81 printf("return %d\n", ffrt::this_task::update_qos(static_cast<int>(ffrt::qos_user_initiated)));
82 printf("id is %" PRIu64 "\n", ffrt::this_task::get_id());
83 });
84 ffrt::this_task::get_id();
85 ffrt::wait();
86 ffrt_this_task_update_qos(static_cast<int>(ffrt::qos_user_initiated));
87 #ifndef WITH_NO_MOCKER
88 ffrt_set_cgroup_attr(static_cast<int>(ffrt::qos_user_initiated), nullptr);
89 #endif
90 }
91
92 HWTEST_F(DependencyTest, update_qos_success_03, TestSize.Level0)
93 {
94 int ret = ffrt_task_attr_init(nullptr);
95 EXPECT_EQ(ret, -1);
__anon014c45000802null96 ffrt::submit([] {
97 printf("return %d\n", ffrt::this_task::update_qos(static_cast<int>(ffrt::qos_user_initiated)));
98 });
99 ffrt_restore_qos_config();
100 ffrt::wait();
101 }
102
103 HWTEST_F(DependencyTest, update_qos_success_04, TestSize.Level0)
104 {
105 int ret = ffrt_task_attr_init(nullptr);
106 EXPECT_EQ(ret, -1);
__anon014c45000902null107 ffrt::submit([] {
108 printf("return %d\n", ffrt::this_task::update_qos(static_cast<int>(ffrt::qos_user_initiated)));
109 });
110 int ret2 = ffrt_set_cpu_worker_max_num(static_cast<int>(ffrt::qos_user_initiated), 4);
111 EXPECT_EQ(ret2, 0);
112 ffrt::wait();
113 }
114
115 HWTEST_F(DependencyTest, update_qos_success_05, TestSize.Level0)
116 {
117 int x = 0;
118 int ret = ffrt_task_attr_init(nullptr);
119 EXPECT_EQ(ret, -1);
120 ffrt_task_attr_get_name(nullptr);
121 ffrt_task_attr_set_name(nullptr, "A");
122 ffrt_task_attr_set_qos(nullptr, static_cast<int>(ffrt::qos_user_initiated));
123 ffrt_task_attr_get_qos(nullptr);
124 ffrt_task_attr_destroy(nullptr);
125 ffrt_submit_base(nullptr, nullptr, nullptr, nullptr);
126 ffrt_submit_h_base(nullptr, nullptr, nullptr, nullptr);
__anon014c45000a02null127 ffrt::submit([&] {
128 x++;
129 printf("return %d\n", ffrt::this_task::update_qos(static_cast<int>(ffrt::qos_user_initiated)));
130 printf("id is %" PRIu64 "\n", ffrt::this_task::get_id());
131 });
132 ffrt_this_task_get_id();
133 ffrt::wait();
134 ffrt_this_task_update_qos(static_cast<int>(ffrt::qos_user_initiated));
135 #ifndef WITH_NO_MOCKER
136 ffrt_os_sched_attr attr = {100, 10, 99, 99, 9, "2-3"};
137 ffrt_set_cgroup_attr(static_cast<int>(ffrt::qos_user_initiated), &attr);
138 #endif
139 EXPECT_EQ(x, 1);
140 }
141
142 HWTEST_F(DependencyTest, update_qos_failed_01, TestSize.Level0)
143 {
144 int x = 0;
145 int ret = ffrt_task_attr_init(nullptr);
146 EXPECT_EQ(ret, -1);
147 ffrt_task_attr_get_name(nullptr);
148 ffrt_task_attr_set_name(nullptr, "A");
149 ffrt_task_attr_set_qos(nullptr, static_cast<int>(ffrt::qos_user_initiated));
150 ffrt_task_attr_get_qos(nullptr);
151 ffrt_task_attr_destroy(nullptr);
152 ffrt_submit_base(nullptr, nullptr, nullptr, nullptr);
153 ffrt_submit_h_base(nullptr, nullptr, nullptr, nullptr);
__anon014c45000b02null154 ffrt::submit([&] {
155 printf("return %d\n", ffrt::this_task::update_qos(static_cast<int>(ffrt::qos_user_initiated)));
156 printf("id is %" PRIu64 "\n", ffrt::this_task::get_id());
157 int ret1 = ffrt_this_task_update_qos(static_cast<int>(ffrt::qos_default));
158 EXPECT_EQ(ret1, 0);
159 x++;
160 });
161 ffrt_this_task_get_id();
162 ffrt::wait();
163 #ifndef WITH_NO_MOCKER
164 ffrt_set_cgroup_attr(static_cast<int>(ffrt::qos_user_initiated), nullptr);
165 #endif
166 EXPECT_EQ(x, 1);
167 }
168
169 HWTEST_F(DependencyTest, update_qos_failed_02, TestSize.Level0)
170 {
171 int ret = ffrt_task_attr_init(nullptr);
172 EXPECT_EQ(ret, -1);
__anon014c45000c02null173 ffrt::submit([] {
174 printf("return %d\n", ffrt::this_task::update_qos(static_cast<int>(ffrt::qos_user_initiated)));
175 });
176 int ret1 = ffrt_set_cpu_worker_max_num(static_cast<int>(ffrt::qos_inherit), 4);
177 EXPECT_EQ(ret1, -1);
178 ffrt::wait();
179 }
180
181 /*
182 * 测试用例名称 :set_worker_min_num_test
183 * 测试用例描述 :测试传入0个线程的情况
184 * 操作步骤 :测试传入0个线程
185 * 预期结果 :预期失败
186 */
187 HWTEST_F(DependencyTest, set_worker_min_num_test, TestSize.Level0)
188 {
189 int ret = ffrt_task_attr_init(nullptr);
190 EXPECT_EQ(ret, -1);
__anon014c45000d02null191 ffrt::submit([] {
192 printf("return %d\n", ffrt::this_task::update_qos(static_cast<int>(ffrt::qos_user_initiated)));
193 });
194 int ret2 = ffrt_set_cpu_worker_max_num(static_cast<int>(ffrt::qos_user_initiated), 0);
195 EXPECT_EQ(ret2, -1);
196 ffrt::wait();
197 }
198
199 /*
200 * 测试用例名称 :set_worker_max_num_test
201 * 测试用例描述 :测试传入超过最大线程数量的情况
202 * 操作步骤 :测试传入160个线程
203 * 预期结果 :预期失败
204 */
205 HWTEST_F(DependencyTest, set_worker_max_num_test, TestSize.Level0)
206 {
207 int ret = ffrt_task_attr_init(nullptr);
208 EXPECT_EQ(ret, -1);
__anon014c45000e02null209 ffrt::submit([] {
210 printf("return %d\n", ffrt::this_task::update_qos(static_cast<int>(ffrt::qos_user_initiated)));
211 });
212 int ret1 = ffrt_set_cpu_worker_max_num(static_cast<int>(ffrt::qos_user_initiated), 160);
213 EXPECT_EQ(ret1, -1);
214 ffrt::wait();
215 }
216
217 HWTEST_F(DependencyTest, ffrt_task_attr_get_name_set_notify_test, TestSize.Level0)
218 {
219 int x = 0;
220 int ret = ffrt_task_attr_init(nullptr);
221 EXPECT_EQ(ret, -1);
222 ffrt_task_attr_t attr;
223 attr.storage[0] = 12345;
224 ffrt_task_attr_set_name(nullptr, "A");
225 ffrt_task_attr_get_name(&attr);
226 ffrt_task_attr_set_notify_worker(&attr, true);
227 ffrt_task_attr_set_notify_worker(nullptr, true);
228 ffrt_task_attr_set_qos(nullptr, static_cast<int>(ffrt::qos_user_initiated));
229 ffrt_task_attr_get_qos(nullptr);
230 ffrt_task_attr_destroy(nullptr);
231 ffrt_submit_base(nullptr, nullptr, nullptr, nullptr);
232 ffrt_submit_h_base(nullptr, nullptr, nullptr, nullptr);
__anon014c45000f02null233 ffrt::submit([&] {
234 printf("return %d\n", ffrt::this_task::update_qos(static_cast<int>(ffrt::qos_user_initiated)));
235 printf("id is %" PRIu64 "\n", ffrt::this_task::get_id());
236 int ret1 = ffrt_this_task_update_qos(static_cast<int>(ffrt::qos_default));
237 EXPECT_EQ(ret1, 0);
238 x++;
239 });
240 ffrt_this_task_get_id();
241 ffrt::wait();
242 ffrt_set_cgroup_attr(static_cast<int>(ffrt::qos_user_initiated), nullptr);
243 EXPECT_EQ(x, 1);
244 }
245
246 HWTEST_F(DependencyTest, executor_task_submit_success_cancel_01, TestSize.Level0)
247 {
248 ffrt_task_attr_t attr;
249 static ffrt_executor_task_t work;
250 work.wq[0] = &work.wq;
251 work.wq[1] = &work.wq;
252 work.type = reinterpret_cast<uintptr_t>(&attr);
253 ffrt_executor_task_submit(nullptr, nullptr);
254
255 ffrt_executor_task_submit(&work, &attr);
256
257 int ret = ffrt_executor_task_cancel(nullptr, static_cast<int>(ffrt::qos_user_initiated));
258 EXPECT_EQ(ret, 0);
259 }
260
261 HWTEST_F(DependencyTest, executor_task_submit_cancel_02, TestSize.Level0)
262 {
263 ffrt_task_attr_t attr;
264 ffrt_task_attr_init(&attr);
265 ffrt_executor_task_t work;
266 work.type = reinterpret_cast<uintptr_t>(&attr);
267
268 ffrt_task_attr_set_qos(&attr, static_cast<int>(ffrt::qos_user_initiated));
269 ffrt_executor_task_submit(&work, &attr);
270 usleep(10000);
271 int cancelled = ffrt_executor_task_cancel(&work, static_cast<int>(ffrt::qos_user_initiated));
272 EXPECT_EQ(cancelled, 0);
273
274 ffrt_task_attr_destroy(&attr);
275 }
276
277 static std::atomic_int uv_sleep = 0;
ffrt_work_sleep(ffrt_executor_task_t * data,ffrt_qos_t qos)278 void ffrt_work_sleep(ffrt_executor_task_t* data, ffrt_qos_t qos)
279 {
280 usleep(1000);
281 uv_sleep++;
282 }
283
init_once_sleep(void)284 static void init_once_sleep(void)
285 {
286 uv_sleep = 0;
287 ffrt_executor_task_register_func(ffrt_work_sleep, ffrt_uv_task);
288 }
289
ThreadSafeRand(const int min,const int max)290 int ThreadSafeRand(const int min, const int max)
291 {
292 /* note that std:mt19937 is not thread-safe,
293 * so each thread has to has its own instance,
294 * or it should be protected by a lock */
295 static thread_local std::mt19937 generator {std::random_device{}()};
296 std::uniform_int_distribution<int> distribution(min, max);
297 return distribution(generator);
298 }
299 /*
300 * 测试用例名称:executor_task_submit_cancel_03
301 * 测试用例描述:uv任务正确取消
302 * 预置条件 :无
303 * 操作步骤 :1、调用注册接口,给uv任务注册一个耗时函数
304 2、提交taskCount个任务
305 3、随机取消taskCount次任务
306 * 预期结果 :1、能够取消至少一个uv任务
307 2、取消的任务数+已执行的任务数=总提交任务数
308 3、取消的任务数>0,已执行的任务数<总提交任务数
309 */
310 HWTEST_F(DependencyTest, executor_task_submit_cancel_03, TestSize.Level0)
311 {
312 const int taskCount = 10000;
313 ffrt_task_attr_t attr;
314 ffrt_task_attr_init(&attr);
315 static ffrt_executor_task_t work[taskCount];
316 init_once_sleep();
317 std::atomic_int cancelCount {0};
318 ffrt::task_attr task_attr;
319 task_attr.qos(ffrt::qos_background);
320 ffrt_task_attr_set_qos(&attr, static_cast<int>(ffrt::qos_user_initiated));
__anon014c45001002() 321 auto tryCancel = [&]() {
322 for (int i = taskCount - 1; i >= 0; --i) {
323 auto idx = ThreadSafeRand(0, taskCount - 1);
324 cancelCount += ffrt_executor_task_cancel(&work[idx], static_cast<int>(ffrt::qos_user_initiated));
325 }
326 };
327 for (int i = 0; i < taskCount; i++) {
328 work[i].type = ffrt_uv_task;
329 ffrt_executor_task_submit(&work[i], &attr);
330 }
331 ffrt::submit(tryCancel, {}, {}, task_attr);
332 ffrt::submit(tryCancel, {}, {}, task_attr);
333 ffrt::wait();
334 sleep(2);
335 EXPECT_LT(uv_sleep, taskCount);
336 EXPECT_GT(uv_sleep, 0);
337 EXPECT_GE(uv_sleep + cancelCount, taskCount);
338 ffrt_task_attr_destroy(&attr);
339 }
340
341 namespace {
342 std::atomic_int uv_result = 0;
343 std::mutex uv_cancel_mtx;
344 std::condition_variable uv_cancel_cv;
345 // libuv's uv__queue
346 struct UvQueue {
347 struct UvQueue* next;
348 struct UvQueue* prev;
349 };
350
351 // libuv's uv__queue_empty
UvQueueEmpty(const struct UvQueue * q)352 inline int UvQueueEmpty(const struct UvQueue* q)
353 {
354 std::lock_guard lg(ffrt::FFRTFacade::GetSchedInstance()->GetScheduler(ffrt::qos_user_initiated).uvMtx);
355 return q == q->next || q != q->next->prev;
356 }
357
UVCbSleep(ffrt_executor_task_t * data,ffrt_qos_t qos)358 void UVCbSleep(ffrt_executor_task_t* data, ffrt_qos_t qos)
359 {
360 (void)data;
361 (void)qos;
362 uv_result.fetch_add(1);
363 std::unique_lock lk(uv_cancel_mtx);
364 uv_cancel_cv.wait(lk);
365 }
366 }
367
368 /*
369 * 测试用例名称 :executor_task_submit_cancel_04
370 * 测试用例描述 :测试通过libuv视角,能够正确取消任务
371 * 操作步骤 :1.提交批量任务,让worker都阻塞,使得所有uv任务都不从Ready中取出
372 * 2.判断uv__queue_empty位false时,调用ffrt_executor_task_cancel取消任务
373 * 预期结果 :能够至少取消一个任务,并且任务执行和取消等于总任务数
374 */
375 HWTEST_F(DependencyTest, executor_task_submit_cancel_04, TestSize.Level1)
376 {
377 uv_result.store(0);
378 constexpr int taskCount = 10000;
379 std::atomic_int cancelCount = 0;
380 std::atomic<bool> flag = false;
381 ffrt_task_attr_t attr;
382 ffrt_task_attr_init(&attr);
383 ffrt_task_attr_set_qos(&attr, static_cast<int>(ffrt::qos_user_initiated));
384 ffrt_executor_task_register_func(UVCbSleep, ffrt_uv_task);
385 ffrt_executor_task_t works[taskCount];
386
387 for (int i = 0; i < taskCount; i++) {
388 ffrt_executor_task_submit(&works[i], &attr);
389 }
390 while (uv_result < 1) {
391 usleep(100);
392 }
__anon014c45001202() 393 thread {[&]() {
394 for (int i = 0; i < taskCount; i++) {
395 if (!UvQueueEmpty(reinterpret_cast<UvQueue*>(&works[i].wq)) &&
396 ffrt_executor_task_cancel(&works[i], ffrt::qos_user_initiated)) {
397 cancelCount.fetch_add(1);
398 flag.store(true, std::memory_order_relaxed);
399 }
400 }
401 }}.detach();
402 while (!flag.load(std::memory_order_relaxed)) {
403 usleep(100);
404 }
405 while (uv_result + cancelCount < taskCount) {
406 usleep(1000);
407 uv_cancel_cv.notify_all();
408 }
409 printf("canceled: %d, result: %d\n", cancelCount.load(), uv_result.load());
410 EXPECT_GT(cancelCount, 0);
411 EXPECT_EQ(cancelCount.load() + uv_result.load(), taskCount);
412 }
413
414 HWTEST_F(DependencyTest, update_trace_tag_task_attr_success, TestSize.Level1)
415 {
416 ffrt::set_trace_tag("TASK A");
417 ffrt::clear_trace_tag();
418
419 ffrt::task_attr tmpTask;
420 tmpTask.name("Task A");
421 tmpTask.qos(static_cast<int>(ffrt::qos_user_initiated));
422
423 EXPECT_EQ(ffrt_task_attr_get_qos(&tmpTask), ffrt::qos_user_initiated);
424 }
425
426 HWTEST_F(DependencyTest, sample_pingpong_pipe_interval_checkpoint, TestSize.Level0)
427 {
428 int loops = 5;
429 int frame_num = 2;
430
431 if (getenv("LOOP_NUM")) {
432 loops = atoi(getenv("LOOP_NUM"));
433 }
434 if (getenv("FRAME_NUM")) {
435 frame_num = atoi(getenv("FRAME_NUM"));
436 }
437
__anon014c45001402() 438 ffrt::submit([&]() { stall_us(10); }, {}, {});
439
440 auto it = ffrt::qos_interval_create(16, static_cast<int>(ffrt::qos_user_interactive));
441 for (int loop = 0; loop < loops; loop++) {
442 constexpr int FRAME_NUM = 3;
443 constexpr uint32_t BUFFER_NUM = 2;
444 int x0[FRAME_NUM];
445 int x1[BUFFER_NUM];
446 int x2[BUFFER_NUM];
447 int x3[FRAME_NUM];
448
449 int stalls[10][4] = {
450 {2000, 6000, 8000, 8000 + 6000 + 2000}, // 0
451 {2125, 6375, 8500, 8500 + 6375 + 2125}, // 1
452 {2222, 6666, 8888, 8888 + 6666 + 2222}, // 2
453 {2250, 6750, 9000, 9000 + 6750 + 2250}, // 3
454 {2375, 7125, 9500, 9500 + 7125 + 2375}, // 4
455 {2500, 7500, 10000, 10000 + 7500 + 2500}, // 5
456 {1875, 5625, 7500, 7500 + 5625 + 1875}, // 6
457 {1750, 5250, 7000, 7000 + 5250 + 1750}, // 7
458 {1625, 4875, 6500, 6500 + 4875 + 1625}, // 8
459 {1500, 4500, 6000, 6000 + 4500 + 1500}, // 9
460 };
461
462 auto start = std::chrono::system_clock::now();
463 ffrt::qos_interval_begin(it);
464 for (int i = 0; i < frame_num; i++) {
465 int pingpong = i % BUFFER_NUM;
466 // task A
467 ffrt::submit(
__anon014c45001602() 468 [i, loop, stalls, &x0, &x1]() {
469 FFRT_LOGI("%u", i);
470 x1[i % BUFFER_NUM] = i;
471 },
__anon014c45001802() 472 {x0 + i}, {x1 + pingpong}, ffrt::task_attr().name(("UI" + std::to_string(i)).c_str()));
473 // task B
474 ffrt::submit(
__anon014c45001902() 475 [i, loop, stalls, &x1, &x2]() {
476 FFRT_LOGI("%u", i);
477 x2[i % BUFFER_NUM] = i;
478 },
__anon014c45001b02() 479 {x1 + pingpong}, {x2 + pingpong}, ffrt::task_attr().name(("Render" + std::to_string(i)).c_str()));
480 // task C
481 ffrt::submit(
__anon014c45001c02() 482 [i, loop, stalls, &x2, &x3]() {
483 FFRT_LOGI("%u", i);
484 x3[i] = i;
485 },
__anon014c45001e02() 486 {x2 + pingpong}, {x3 + i}, ffrt::task_attr().name(("surfaceflinger" + std::to_string(i)).c_str()));
487 }
488 ffrt::wait();
489 ffrt::qos_interval_end(it);
490
491 for (int i = 0; i < frame_num; i++) {
492 EXPECT_EQ(x3[i], i) << "Task C result is incorrect for frame " << i;
493 }
494 }
495
496 ffrt::qos_interval_destroy(it);
497 }
498
AddOne(void * args)499 void AddOne(void* args)
500 {
501 *(static_cast<int*>(args)) += 1;
502 }
503
504 namespace {
505 ffrt::mutex uv_block_mtx;
506 std::atomic_int uv_block_result = 0;
507 const unsigned int UV_BLOCK_SLEEP_TIME = 10;
UVBlockCb(ffrt_executor_task_t * data,ffrt_qos_t qos)508 void UVBlockCb(ffrt_executor_task_t* data, ffrt_qos_t qos)
509 {
510 (void)qos;
511 std::unique_lock lk(uv_block_mtx);
512 usleep(UV_BLOCK_SLEEP_TIME);
513 uv_block_result.fetch_add(1);
514 }
Rand()515 int Rand()
516 {
517 std::random_device rd;
518 std::mt19937 gen(rd());
519 constexpr int min = 1;
520 constexpr int max = 20;
521 std::uniform_int_distribution<int> dis(min, max);
522 return dis(gen);
523 }
524 }
525
526 HWTEST_F(DependencyTest, uv_task_block_ffrt_mutex, TestSize.Level0)
527 {
528 ffrt_executor_task_register_func(UVBlockCb, ffrt_uv_task);
529 const int taskCount = 4000;
__anon014c45002002() 530 auto submitNormal = []() {
531 for (int qos = ffrt_qos_background; qos <= ffrt_qos_user_initiated; qos++) {
532 ffrt::submit([]() {
533 usleep(1);
534 }, {}, {}, ffrt::task_attr().qos(qos));
535 usleep(Rand());
536 }
537 };
__anon014c45002402() 538 auto t1 = std::thread{[submitNormal]() {
539 for (int i = 0; i < taskCount; i++) {
540 if (uv_block_result >= taskCount * 4) {
541 break;
542 }
543 submitNormal();
544 }
545 ffrt::wait();
546 }};
547 ffrt_executor_task_t uvWork[taskCount * 4];
__anon014c45002502() 548 auto t2 = std::thread{[&]() {
549 ffrt_task_attr_t attr;
550 ffrt_task_attr_init(&attr);
551 for (int i = 0; i < taskCount; i++) {
552 ffrt_task_attr_set_qos(&attr, ffrt_qos_background);
553 ffrt_executor_task_submit(&uvWork[i * 4], &attr);
554 usleep(Rand());
555 ffrt_task_attr_set_qos(&attr, ffrt_qos_utility);
556 ffrt_executor_task_submit(&uvWork[i * 4 + 1], &attr);
557 usleep(Rand());
558 ffrt_task_attr_set_qos(&attr, ffrt_qos_default);
559 ffrt_executor_task_submit(&uvWork[i * 4 + 2], &attr);
560 usleep(Rand());
561 ffrt_task_attr_set_qos(&attr, ffrt_qos_user_initiated);
562 ffrt_executor_task_submit(&uvWork[i * 4 + 3], &attr);
563 }
564 }};
565 while (uv_block_result < taskCount * 4) {
566 usleep(1000);
567 }
568 EXPECT_EQ(uv_block_result, taskCount * 4);
569 t1.join();
570 t2.join();
571 }
572
573 HWTEST_F(DependencyTest, onsubmit_test, TestSize.Level0)
574 {
575 ffrt_task_handle_t handle = nullptr;
__anon014c45002602() 576 std::function<void()> cbOne = []() { printf("callback\n"); };
577 ffrt_function_header_t* func = ffrt::create_function_wrapper(cbOne, ffrt_function_kind_general);
578 ffrt::SDependenceManager* manager = new ffrt::SDependenceManager();
579 manager->onSubmit(true, handle, func, nullptr, nullptr, nullptr);
580
581 const std::vector<ffrt_dependence_t> wait_deps = {{ffrt_dependence_task, handle}};
582 ffrt_deps_t wait{static_cast<uint32_t>(wait_deps.size()), wait_deps.data()};
583 manager->onSubmit(true, handle, func, nullptr, &wait, nullptr);
584 manager->onWait(&wait);
585 EXPECT_NE(func, nullptr);
586 delete manager;
587 }
588