• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <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