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