• 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 <random>
17 #include <csignal>
18 #include <gtest/gtest.h>
19 #include "core/entity.h"
20 #include "core/version_ctx.h"
21 #include "ffrt_inner.h"
22 #include "c/ffrt_ipc.h"
23 #include "dfx/log/ffrt_log_api.h"
24 #include "dfx/bbox/bbox.h"
25 #include "tm/cpu_task.h"
26 #include "tm/io_task.h"
27 #include "tm/queue_task.h"
28 #include "tm/scpu_task.h"
29 #include "tm/task_factory.h"
30 #include "../common.h"
31 
32 using namespace std;
33 using namespace testing;
34 #ifdef HWTEST_TESTING_EXT_ENABLE
35 using namespace testing::ext;
36 #endif
37 using namespace ffrt;
38 
39 class CoreTest : public testing::Test {
40 protected:
SetUpTestCase()41     static void SetUpTestCase()
42     {
43     }
44 
TearDownTestCase()45     static void TearDownTestCase()
46     {
47     }
48 
SetUp()49     void SetUp() override
50     {
51     }
52 
TearDown()53     void TearDown() override
54     {
55     }
56 };
57 
58 #if defined(__clang__)
59 #define OPTIMIZE_OFF __attribute__((optnone))
60 #elif defined(__GNUC__)
61 #define OPTIMIZE_OFF __attribute__((optimize(0)))
62 #else
63 #define OPTIMIZE_OFF
64 #endif
65 
66 namespace {
OnePlusForTest(void * data)67 void OPTIMIZE_OFF OnePlusForTest(void* data)
68 {
69     *(int*)data += 1;
70 }
71 } // namespace
72 
73 HWTEST_F(CoreTest, task_ctx_success_01, TestSize.Level0)
74 {
__anon188ecaea0202() 75     auto func1 = ([]() {std::cout << std::endl << " push a task " << std::endl;});
76     task_attr_private attr;
77     attr.qos_ = qos_user_interactive;
78     SCPUEUTask *task1 = new SCPUEUTask(&attr, nullptr, 0);
__anon188ecaea0302() 79     auto func2 = ([]() {std::cout << std::endl << " push a task " << std::endl;});
80     SCPUEUTask *task2 = new SCPUEUTask(nullptr, task1, 0);
81     QoS qos = QoS(static_cast<int>(qos_inherit));
82     task2->SetQos(qos);
83     EXPECT_EQ(task2->qos_, static_cast<int>(qos_user_interactive));
84     delete task1;
85     delete task2;
86 }
87 
88 /**
89  * @tc.name: TaskBlockTypeCheck
90  * @tc.desc: Test function of TaskBase::Block and TaskBase::Wake
91  * @tc.type: FUNC
92  */
93 HWTEST_F(CoreTest, TaskBlockTypeCheck, TestSize.Level0)
94 {
95     SCPUEUTask* task = new SCPUEUTask(nullptr, nullptr, 0);
96 
97     // when executing task is root
98     EXPECT_EQ(task->GetBlockType(), BlockType::BLOCK_THREAD);
99 
100     // when executing task is nullptr
101     EXPECT_EQ(task->Block(), BlockType::BLOCK_THREAD);
102 
103     auto parent = new SCPUEUTask(nullptr, nullptr, 0);
104     task->parent = parent;
105 
106     auto expectedBlockType = USE_COROUTINE? BlockType::BLOCK_COROUTINE :  BlockType::BLOCK_THREAD;
107     // when task is not in legacy mode
108     EXPECT_EQ(task->Block(), expectedBlockType);
109     EXPECT_EQ(task->GetBlockType(), expectedBlockType);
110     task->Wake();
111 
112     // when task is in legacy mode
113     task->legacyCountNum++;
114     EXPECT_EQ(task->Block(), BlockType::BLOCK_THREAD);
115     EXPECT_EQ(task->GetBlockType(), BlockType::BLOCK_THREAD);
116     task->Wake();
117 
118     // when task's legacy mode canceled
119     task->legacyCountNum--;
120     EXPECT_EQ(task->Block(), expectedBlockType);
121     EXPECT_EQ(task->GetBlockType(), expectedBlockType);
122 
123     delete parent;
124     delete task;
125 }
126 
127 /**
128  * 测试用例名称:task_attr_set_timeout
129  * 测试用例描述:验证task_attr的设置timeout接口
130  * 预置条件:创建有效的task_attr
131  * 操作步骤:设置timeout值,通过get接口与设置值对比
132  * 预期结果:设置成功
133  */
134 HWTEST_F(CoreTest, task_attr_set_timeout, TestSize.Level0)
135 {
136     ffrt_task_attr_t* attr = (ffrt_task_attr_t *) malloc(sizeof(ffrt_task_attr_t));
137     ffrt_task_attr_init(attr);
138     ffrt_task_attr_set_timeout(attr, 1000);
139     uint64_t timeout = ffrt_task_attr_get_timeout(attr);
140     EXPECT_EQ(timeout, 1000);
141     ffrt_task_attr_set_timeout(attr, UINT64_MAX); // 测试时间溢出截断功能
142     uint64_t maxUsCount = 1000000ULL * 100 * 60 * 60 * 24 * 365; // 100 year
143     EXPECT_EQ(ffrt_task_attr_get_timeout(attr), maxUsCount);
144     free(attr);
145 }
146 
147 /**
148  * 测试用例名称:task_attr_set_timeout_nullptr
149  * 测试用例描述:验证task_attr的设置timeout接口的异常场景
150  * 预置条件:针对nullptr进行设置
151  * 操作步骤:设置timeout值,通过get接口与设置值对比
152  * 预期结果:设置失败,返回值为0
153  */
154 HWTEST_F(CoreTest, task_attr_set_timeout_nullptr, TestSize.Level0)
155 {
156     ffrt_task_attr_t* attr = nullptr;
157     ffrt_task_attr_set_timeout(attr, 1000);
158     uint64_t timeout = ffrt_task_attr_get_timeout(attr);
159     EXPECT_EQ(timeout, 0);
160 }
161 
162 /**
163  * 测试用例名称:task_attr_set_stack_size
164  * 测试用例描述:验证task_attr的设置stack_size接口
165  * 预置条件:创建有效的task_attr
166  * 操作步骤:设置stack_size值,通过get接口与设置值对比
167  * 预期结果:设置成功
168  */
169 HWTEST_F(CoreTest, task_attr_set_stack_size, TestSize.Level0)
170 {
171     ffrt_task_attr_t* attr = (ffrt_task_attr_t *) malloc(sizeof(ffrt_task_attr_t));
172     ffrt_task_attr_init(attr);
173     ffrt_task_attr_set_stack_size(attr, 1024 * 1024);
174     uint64_t stackSize = ffrt_task_attr_get_stack_size(attr);
175     EXPECT_EQ(stackSize, 1024 * 1024);
176     free(attr);
177 }
178 
179 /**
180  * 测试用例名称:ffrt_task_handle_ref_nullptr
181  * 测试用例描述:验证task_handle的增加、消减引用计数接口的异常场景
182  * 预置条件:针对nullptr进行设置
183  * 操作步骤:对nullptr进行调用
184  * 预期结果:接口校验异常场景成功,用例正常执行结束
185  */
186 HWTEST_F(CoreTest, ffrt_task_handle_ref_nullptr, TestSize.Level0)
187 {
188     ffrt_task_handle_t handle = nullptr;
189     ffrt_task_handle_inc_ref(handle);
190     ffrt_task_handle_dec_ref(handle);
191     EXPECT_EQ(handle, nullptr);
192 }
193 
194 /**
195  * 测试用例名称:ffrt_task_handle_ref
196  * 测试用例描述:验证task_handle的增加、消减引用计数接口
197  * 预置条件:创建有效的task_handle
198  * 操作步骤:对task_handle进行设置引用计数接口
199  * 预期结果:读取rc值
200  */
201 HWTEST_F(CoreTest, ffrt_task_handle_ref, TestSize.Level0)
202 {
203     // 验证notify_worker的功能
204     int result = 0;
205     ffrt_task_attr_t taskAttr;
206     (void)ffrt_task_attr_init(&taskAttr); // 初始化task属性,必须
207     ffrt_task_attr_set_delay(&taskAttr, 10000); // 延时10ms执行
__anon188ecaea0402() 208     std::function<void()>&& OnePlusFunc = [&result]() { result += 1; };
209     ffrt_task_handle_t handle = ffrt_submit_h_base(ffrt::create_function_wrapper(OnePlusFunc), {}, {}, &taskAttr);
210     EXPECT_GT(ffrt_task_handle_get_id(handle), 0);
211     auto task = static_cast<ffrt::CPUEUTask*>(handle);
212     EXPECT_EQ(task->rc.load(), 2); // task还未执行完成,所以task和handle各计数一次
213     ffrt_task_handle_inc_ref(handle);
214     EXPECT_EQ(task->rc.load(), 3);
215     ffrt_task_handle_dec_ref(handle);
216     EXPECT_EQ(task->rc.load(), 2);
217     ffrt::wait({handle});
218     EXPECT_EQ(result, 1);
219     ffrt_task_handle_destroy(handle);
220 }
221 
222 /**
223  * 测试用例名称:WaitFailWhenReuseHandle
224  * 测试用例描述:构造2个submit_h的任务,验证task_handle转成dependence后,调用ffrt::wait的场景
225  * 预置条件:创建一个submit_h任务,确保执行完成,且将task_handle转成dependence后保存
226  * 操作步骤:创建另外一个task_handle任务,并且先执行ffrt::wait保存的dependence的数组
227  * 预期结果:任务正常执行结束
228  */
229 HWTEST_F(CoreTest, WaitFailWhenReuseHandle, TestSize.Level0)
230 {
231     int i = 0;
232     std::vector<ffrt::dependence> deps;
233     {
__anon188ecaea0502null234         auto h = ffrt::submit_h([&i] { printf("task0 done\n"); i++;});
235         printf("task0 handle: %p\n:", static_cast<void*>(h));
236         ffrt::dependence d(h);
237         ffrt::dependence dep = d;
238         deps.emplace_back(dep);
239     }
240     usleep(1000);
241     std::atomic_bool stop = false;
__anon188ecaea0602null242     auto h = ffrt::submit_h([&] {
243         printf("task1 start\n");
244         while (!stop);
245         i++;
246         printf("task1 done\n");
247         });
248     ffrt::wait(deps);
249     EXPECT_EQ(i, 1);
250     stop = true;
251     ffrt::wait();
252     EXPECT_EQ(i, 2);
253 }
254 
255 /*
256  * 测试用例名称:ffrt_task_get_tid_test
257  * 测试用例描述:测试ffrt_task_get_tid接口
258  * 预置条件    :创建SCPUEUTask
259  * 操作步骤    :调用ffrt_task_get_tid方法,入参分别为SCPUEUTask、QueueTask对象和空指针
260  * 预期结果    :ffrt_task_get_tid功能正常,传入空指针时返回0
261  */
262 HWTEST_F(CoreTest, ffrt_task_get_tid_test, TestSize.Level0)
263 {
264     ffrt::CPUEUTask* task = new ffrt::SCPUEUTask(nullptr, nullptr, 0);
265     ffrt::QueueTask* queueTask = new ffrt::QueueTask(nullptr);
266     pthread_t tid = ffrt_task_get_tid(task);
267     EXPECT_EQ(tid, 0);
268 
269     tid = ffrt_task_get_tid(queueTask);
270     EXPECT_EQ(tid, 0);
271 
272     tid = ffrt_task_get_tid(nullptr);
273     EXPECT_EQ(tid, 0);
274 
275     delete task;
276     delete queueTask;
277 }
278 
279 /*
280 * 测试用例名称:ffrt_get_cur_cached_task_id_test
281 * 测试用例描述:测试ffrt_get_cur_cached_task_id接口
282 * 预置条件    :设置ExecuteCtx::Cur->lastGid_为自定义值
283 * 操作步骤    :调用ffrt_get_cur_cached_task_id接口
284 * 预期结果    :ffrt_get_cur_cached_task_id返回值与自定义值相同
285 */
286 HWTEST_F(CoreTest, ffrt_get_cur_cached_task_id_test, TestSize.Level0)
287 {
288     auto ctx = ffrt::ExecuteCtx::Cur();
289     ctx->lastGid_ = 15;
290     EXPECT_EQ(ffrt_get_cur_cached_task_id(), 15);
291 
__anon188ecaea0702null292     ffrt::submit([] {});
293     ffrt::wait();
294 
295     EXPECT_NE(ffrt_get_cur_cached_task_id(), 0);
296 }
297 
298 /*
299 * 测试用例名称:ffrt_skip_task_test
300 * 测试用例描述:测试ffrt_skip接口
301 * 预置条件    :无
302 * 操作步骤    :1.提交普通延时执行的任务,不notifyworker,并获取句柄
303                2.调用ffrt_skip接口,入参为句柄
304 * 预期结果    :任务取消成功
305 */
306 HWTEST_F(CoreTest, ffrt_skip_task_test, TestSize.Level0)
307 {
__anon188ecaea0802() 308     auto h = ffrt::submit_h([]() {}, {}, {}, ffrt::task_attr().delay(10000)); // 10ms
309     int cancel_ret = ffrt::skip(h);
310     EXPECT_EQ(cancel_ret, 0);
311     ffrt::wait();
312 }
313 
314 /*
315 * 测试用例名称:ffrt_get_cur_task_test
316 * 测试用例描述:测试ffrt_get_cur_task接口
317 * 预置条件    :提交ffrt任务
318 * 操作步骤    :1.在ffrt任务中调用ffrt_get_cur_task接口
319                2.在非ffrt任务中调用ffrt_get_cur_task接口
320 * 预期结果    :1.返回的task地址不为空
321                2.返回的task地址不为空
322 */
323 HWTEST_F(CoreTest, ffrt_get_cur_task_test, TestSize.Level0)
324 {
325     void* taskPtr = nullptr;
__anon188ecaea0b02null326     ffrt::submit([&] {
327         taskPtr = ffrt_get_cur_task();
328     });
329     ffrt::wait();
330 
331     EXPECT_NE(taskPtr, nullptr);
332     taskPtr = ffrt_get_cur_task();
333     EXPECT_EQ(taskPtr, nullptr);
334 }
335 
336 /*
337 * 测试用例名称:ffrt_this_task_get_qos_test
338 * 测试用例描述:测试ffrt_this_task_get_qos接口
339 * 预置条件    :提交qos=3的ffrt任务
340 * 操作步骤    :在ffrt任务中调用ffrt_this_task_get_qos接口
341 * 预期结果    :ffrt_this_task_get_qos返回值=3
342 */
343 HWTEST_F(CoreTest, ffrt_this_task_get_qos_test, TestSize.Level0)
344 {
345     ffrt_qos_t qos = 0;
__anon188ecaea0c02null346     ffrt::submit([&] {
347         qos = ffrt_this_task_get_qos();
348     }, ffrt::task_attr().qos(ffrt_qos_user_initiated));
349     ffrt::wait();
350     EXPECT_EQ(qos, ffrt::QoS(ffrt_qos_user_initiated)());
351 }
352 
353 /*
354 * 测试用例名称:ffrt_set_sched_mode
355 * 测试用例描述:ffrt_set_sched_mode EU调度模式设置
356 * 预置条件    :NA
357 * 操作步骤    :在非ffrt任务中调用ffrt_set_sched_mode接口
358 * 预期结果    :设置EU调度策略为默认模式、性能模式或节能模式
359 */
360 HWTEST_F(CoreTest, ffrt_set_sched_mode, TestSize.Level0)
361 {
362     ffrt::sched_mode_type sched_type = ffrt::ExecuteUnit::Instance().GetSchedMode(ffrt::QoS(ffrt::qos_default));
363     EXPECT_EQ(static_cast<int>(sched_type), static_cast<int>(ffrt::sched_mode_type::sched_default_mode));
364 
365     ffrt_set_sched_mode(ffrt::QoS(ffrt::qos_default), ffrt_sched_energy_saving_mode);
366     sched_type = ffrt::ExecuteUnit::Instance().GetSchedMode(ffrt::QoS(ffrt::qos_default));
367     EXPECT_EQ(static_cast<int>(sched_type), static_cast<int>(ffrt::sched_mode_type::sched_energy_saving_mode));
368 
369     ffrt_set_sched_mode(ffrt::QoS(ffrt::qos_default), ffrt_sched_performance_mode);
370     sched_type = ffrt::ExecuteUnit::Instance().GetSchedMode(ffrt::QoS(ffrt::qos_default));
371     EXPECT_EQ(static_cast<int>(sched_type), static_cast<int>(ffrt::sched_mode_type::sched_performance_mode));
372     ffrt_set_sched_mode(ffrt::QoS(ffrt::qos_default), ffrt_sched_default_mode);
373 }
374 
375 /*
376 * 测试用例名称:ffrt_set_worker_stack_size
377 * 测试用例描述:ffrt_set_worker_stack_size 设置worker线程栈大小
378 * 预置条件    :NA
379 * 操作步骤    :在非ffrt任务中调用ffrt_set_worker_stack_size接口
380 * 预期结果    :能够处理正常和异常stackSize和qos的值
381 */
382 HWTEST_F(CoreTest, ffrt_set_worker_stack_size, TestSize.Level0)
383 {
384     ffrt_error_t ret;
385     int qosMin = ffrt_qos_background;
386     int qosMax = ffrt::QoS::Max();
387     int stackSizeMin = PTHREAD_STACK_MIN;
388     // 设置异常Qos
389     ret = ffrt::set_worker_stack_size(qosMin - 1, stackSizeMin);
390     EXPECT_EQ(ret, ffrt_error_inval);
391     ret = ffrt::set_worker_stack_size(qosMax, stackSizeMin);
392     EXPECT_EQ(ret, ffrt_error_inval);
393 
394     // 设置异常stacksize
395     ret = ffrt::set_worker_stack_size(qosMin, stackSizeMin - 1);
396     EXPECT_EQ(ret, ffrt_error_inval);
397 }
398 
399 namespace ffrt {
400 template <typename T>
Instance()401 TaskFactory<T>& TaskFactory<T>::Instance()
402 {
403     static TaskFactory<T> fac;
404     return fac;
405 }
406 }
407 
408 namespace TmTest {
409 class MyTask : public ffrt::TaskBase {
410 public:
MyTask()411     MyTask() : ffrt::TaskBase(ffrt_invalid_task, nullptr) {}
412 private:
FreeMem()413     void FreeMem() override { ffrt::TaskFactory<MyTask>::Free(this); }
Prepare()414     void Prepare() override {}
Ready()415     void Ready() override {}
Pop()416     void Pop() override {}
Cancel()417     void Cancel() override {}
Finish()418     void Finish() override {}
Execute()419     void Execute() override {}
Block()420     ffrt::BlockType Block() override { return ffrt::BlockType::BLOCK_THREAD; }
Wake()421     void Wake() override {}
SetQos(const QoS & newQos)422     void SetQos(const QoS& newQos) override {}
GetLabel() const423     std::string GetLabel() const override { return "my-task"; }
GetBlockType() const424     ffrt::BlockType GetBlockType() const override { return ffrt::BlockType::BLOCK_THREAD; }
425 };
426 
TestTaskFactory(bool isSimpleAllocator)427 void TestTaskFactory(bool isSimpleAllocator)
428 {
429     MyTask* task = ffrt::TaskFactory<MyTask>::Alloc();
430     uint32_t taskCount = ffrt::TaskFactory<MyTask>::GetUnfreedMem().size();
431     EXPECT_EQ(taskCount, ffrt::TaskFactory<MyTask>::GetUnfreedMemSize());
432 #ifdef FFRT_BBOX_ENABLE
433     EXPECT_FALSE(ffrt::TaskFactory<MyTask>::HasBeenFreed(task));
434 #else
435     EXPECT_TRUE(isSimpleAllocator || !ffrt::TaskFactory<MyTask>::HasBeenFreed(task));
436 #endif
437 
438     std::vector<ffrt::TaskBase*> tasks;
439     new(task) MyTask();
440     tasks.push_back(task);
441     for (auto task : tasks) {
442         task->DecDeleteRef();
443     }
444 
445     uint32_t newCount = ffrt::TaskFactory<MyTask>::GetUnfreedMem().size();
446     EXPECT_EQ(newCount, ffrt::TaskFactory<MyTask>::GetUnfreedMemSize());
447 #ifdef FFRT_BBOX_ENABLE
448     EXPECT_GT(taskCount, newCount);
449 #else
450     if (!isSimpleAllocator) {
451         EXPECT_GT(taskCount, ffrt::TaskFactory<MyTask>::GetUnfreedMem().size());
452     }
453 #endif
454     EXPECT_TRUE(ffrt::TaskFactory<MyTask>::HasBeenFreed(task));
455 }
456 
457 template <typename T>
458 class CustomTaskManager {
459 public:
Alloc()460     T* Alloc()
461     {
462         mutex.lock();
463         T* res = reinterpret_cast<T*>(malloc(sizeof(T)));
464         allocedTask.insert(res);
465         mutex.unlock();
466         return res;
467     }
468 
Free(T * task)469     void Free(T* task)
470     {
471         mutex.lock();
472         allocedTask.erase(task);
473         free(task);
474         mutex.unlock();
475     }
476 
LockMem()477     void LockMem()
478     {
479         mutex.lock();
480     }
481 
UnlockMem()482     void UnlockMem()
483     {
484         mutex.unlock();
485     }
486 
HasBeenFreed(T * task)487     bool HasBeenFreed(T* task)
488     {
489         return allocedTask.find(task) == allocedTask.end();
490     }
491 
GetUnfreedMem()492     std::vector<void*> GetUnfreedMem()
493     {
494         std::vector<void*> res;
495         res.reserve(allocedTask.size());
496         std::transform(allocedTask.begin(), allocedTask.end(), std::inserter(res, res.end()), [](T* ptr) {
497             return static_cast<void*>(ptr);
498         });
499         return res;
500     }
501 
GetUnfreedMemSize()502     std::size_t GetUnfreedMemSize()
503     {
504         return allocedTask.size();
505     }
506 
507 private:
508     std::mutex mutex;
509     std::set<T*> allocedTask;
510 };
511 } // namespace TmTest
512 
513 /*
514 * 测试用例名称:ffrt_task_factory_test_001
515 * 测试用例描述:测试使用SimpleAllocator时,任务能够成功申请释放
516 * 预置条件    :注册使用SimpleAllocator的内存分配函数
517 * 操作步骤    :使用TaskFactory申请一个自定义Task的实例,初始化后调用各自的DecDeleteRef释放
518 * 预期结果    :能够正常申请和释放,释放前后GetUnFreedMem读取数组的值小于释放前
519 */
520 HWTEST_F(CoreTest, ffrt_task_factory_test_001, TestSize.Level0)
521 {
522     ffrt::TaskFactory<TmTest::MyTask>::RegistCb(
523         ffrt::SimpleAllocator<TmTest::MyTask>::AllocMem,
524         ffrt::SimpleAllocator<TmTest::MyTask>::FreeMem,
525         ffrt::SimpleAllocator<TmTest::MyTask>::FreeMem_,
526         ffrt::SimpleAllocator<TmTest::MyTask>::getUnfreedMem,
527         ffrt::SimpleAllocator<TmTest::MyTask>::getUnfreedMemSize,
528         ffrt::SimpleAllocator<TmTest::MyTask>::HasBeenFreed,
529         ffrt::SimpleAllocator<TmTest::MyTask>::LockMem,
530         ffrt::SimpleAllocator<TmTest::MyTask>::UnlockMem);
531 
532     TmTest::TestTaskFactory(true);
533 }
534 
535 /*
536 * 测试用例名称:ffrt_task_factory_test_002
537 * 测试用例描述:测试使用自定义管理器时,任务能够成功申请释放
538 * 预置条件    :注册自定义Task内存分配函数
539 * 操作步骤    :使用TaskFactory申请一个自定义Task的实例,初始化后调用各自的DecDeleteRef释放
540 * 预期结果    :能够正常申请和释放,释放前后GetUnFreedMem读取数组的值小于释放前
541 */
542 HWTEST_F(CoreTest, ffrt_task_factory_test_002, TestSize.Level0)
543 {
544     TmTest::CustomTaskManager<TmTest::MyTask> custom_manager;
545     ffrt::TaskFactory<TmTest::MyTask>::RegistCb(
__anon188ecaea0e02() 546         [&] () -> TmTest::MyTask* { return custom_manager.Alloc(); },
__anon188ecaea0f02(TmTest::MyTask* task) 547         [&] (TmTest::MyTask* task) { custom_manager.Free(task); },
__anon188ecaea1002(TmTest::MyTask* task) 548         [&] (TmTest::MyTask* task) { custom_manager.Free(task); },
__anon188ecaea1102() 549         [&] () -> std::vector<void*> { return custom_manager.GetUnfreedMem(); },
__anon188ecaea1202() 550         [&] () -> std::size_t { return custom_manager.GetUnfreedMemSize(); },
__anon188ecaea1302(TmTest::MyTask* task) 551         [&] (TmTest::MyTask* task) { return custom_manager.HasBeenFreed(task); },
__anon188ecaea1402() 552         [&] () { custom_manager.LockMem(); },
__anon188ecaea1502() 553         [&] () { custom_manager.UnlockMem(); });
554 
555     TmTest::TestTaskFactory(false);
556 }
557 
558 HWTEST_F(CoreTest, ffrt_submit_h_f, TestSize.Level0)
559 {
560     ffrt_task_attr_t attr;
561     (void)ffrt_task_attr_init(&attr);
562 
563     int result = 0;
564     ffrt_task_handle_t task = ffrt_submit_h_f(OnePlusForTest, &result, nullptr, nullptr, &attr);
565     const std::vector<ffrt_dependence_t> wait_deps = {{ffrt_dependence_task, task}};
566     ffrt_deps_t wait{static_cast<uint32_t>(wait_deps.size()), wait_deps.data()};
567     ffrt_wait_deps(&wait);
568     ffrt_task_handle_destroy(task);
569 
570     EXPECT_EQ(result, 1);
571 }
572 
573 /*
574 * 测试用例名称:ffrt_task_factory_test_003
575 * 测试用例描述:测试使用SimpleAllocator时,UVTask的TaskFactory接口正常
576 * 预置条件    :无
577 * 操作步骤    :1.向TaskFactory申请一个UVTask实例
578                2.调用TaskFactory的HasBeenFreed、Free_接口
579 * 预期结果    :任务是否释放符合预期
580 */
581 HWTEST_F(CoreTest, ffrt_task_factory_test_003, TestSize.Level0)
582 {
583     ffrt::UVTask* task = ffrt::TaskFactory<ffrt::UVTask>::Alloc();
584     EXPECT_EQ(ffrt::TaskFactory<ffrt::UVTask>::HasBeenFreed(task), false);
585     ffrt::TaskFactory<ffrt::UVTask>::Free_(task);
586     EXPECT_EQ(ffrt::TaskFactory<ffrt::UVTask>::HasBeenFreed(task), true);
587 }
588 
589 HWTEST_F(CoreTest, ffrt_submit_f, TestSize.Level0)
590 {
591     ffrt_task_attr_t attr;
592     (void)ffrt_task_attr_init(&attr);
593 
594     int result = 0;
595     ffrt_submit_f(OnePlusForTest, &result, nullptr, nullptr, &attr);
596     ffrt::wait();
597     EXPECT_EQ(result, 1);
598 }
599 
600 HWTEST_F(CoreTest, ffrt_core_test, TestSize.Level0)
601 {
__anon188ecaea1602() 602     std::function<void()> cbOne = []() { printf("callback\n"); };
603     ffrt_function_header_t* func = ffrt::create_function_wrapper(cbOne, ffrt_function_kind_general);
604     uint64_t size = 1 * 1024 * 1024;
605     ffrt_task_attr_t task_attr;
606     (void)ffrt_task_attr_init(&task_attr);
607     ffrt_task_handle_t handle = ffrt_submit_h_base(func, {}, {}, &task_attr);
608     ffrt_task_handle_get_id(handle);
609 
610     ffrt_task_attr_init(nullptr);
611     ffrt_task_attr_destroy(nullptr);
612     ffrt_task_attr_set_name(&task_attr, nullptr);
613     ffrt_task_attr_get_name(&task_attr);
614     const char * name = ffrt_task_attr_get_name(nullptr);
615     EXPECT_EQ(name, nullptr);
616     ffrt_task_attr_set_stack_size(&task_attr, size);
617     ffrt_task_attr_set_stack_size(nullptr, size);
618     uint64_t id = ffrt_task_handle_get_id(nullptr);
619     EXPECT_EQ(id, 0);
620     ffrt::wait({handle});
621 }
622 
623 /*
624  * 测试用例名称: ffrt_task_factory_deleteRef_test
625  * 测试用例描述: 测试使用自定义管理器时,在并发情况下增减引用计数接口正常
626  * 预置条件    : 注册自定义Task内存分配函数
627  * 操作步骤    : 创建2批线程,分别使用自定义管理器创建任务并减少引用计数和获取尝试增加引用计数成功的任务并减少引用计数
628  * 预期结果    : 任务引用计数符合预期
629 */
630 HWTEST_F(CoreTest, ffrt_task_factory_deleteRef_test, TestSize.Level0)
631 {
632     ffrt::TaskFactory<TmTest::MyTask>::RegistCb(
633         ffrt::SimpleAllocator<TmTest::MyTask>::AllocMem,
634         ffrt::SimpleAllocator<TmTest::MyTask>::FreeMem,
635         ffrt::SimpleAllocator<TmTest::MyTask>::FreeMem_,
636         ffrt::SimpleAllocator<TmTest::MyTask>::getUnfreedMem,
637         ffrt::SimpleAllocator<TmTest::MyTask>::getUnfreedMemSize,
638         ffrt::SimpleAllocator<TmTest::MyTask>::HasBeenFreed,
639         ffrt::SimpleAllocator<TmTest::MyTask>::LockMem,
640         ffrt::SimpleAllocator<TmTest::MyTask>::UnlockMem);
641 
642     int threadCnt = 100;
643     std::thread decDeleteRefThreads[threadCnt];
644     std::thread incDeleteRefThreads[threadCnt];
645     for (int threadIndex = 0; threadIndex < threadCnt; threadIndex++) {
__anon188ecaea1702null646         decDeleteRefThreads[threadIndex] = std::thread([&] {
647             std::vector<TmTest::MyTask*> tasks;
648             int taskCount = 1000;
649             for (int i = 0; i < taskCount; i++) {
650                 TmTest::MyTask* task = ffrt::TaskFactory<TmTest::MyTask>::Alloc();
651                 new(task) TmTest::MyTask();
652                 tasks.push_back(task);
653             }
654             for (auto& task : tasks) {
655                 EXPECT_TRUE(task->DecDeleteRef() > 0);
656             }
657         });
658 
__anon188ecaea1802null659         incDeleteRefThreads[threadIndex] = std::thread([&] {
660             std::vector<void*> unfreeVec = TaskFactory<TmTest::MyTask>::GetUnfreedTasksFiltered();
661             for (auto& unfree : unfreeVec) {
662                 auto t = reinterpret_cast<TmTest::MyTask*>(unfree);
663                 EXPECT_TRUE(t->DecDeleteRef() > 0);
664             }
665         });
666     }
667 
668     for (auto& t : decDeleteRefThreads) {
669         t.join();
670     }
671     for (auto& t : incDeleteRefThreads) {
672         t.join();
673     }
674 }
675