1 /*
2 * Copyright (c) 2024 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 "test.h"
17
18 #include "napi/native_api.h"
19 #include "napi/native_node_api.h"
20 #include "sequence_runner.h"
21 #include "task.h"
22 #include "task_group.h"
23 #include "task_manager.h"
24 #include "taskpool.h"
25 #include "utils.h"
26 #include "uv.h"
27 #include "worker.h"
28
29 namespace Commonlibrary::Concurrent::TaskPoolModule {
30
31 static constexpr uint32_t MAX_TIMEOUT_TIME = 600000;
32 static constexpr uint32_t FINSHED_TASK_ = 5;
33 static constexpr uint32_t TASK_NUMS_ = 7;
34 static constexpr uint64_t UINT64_ZERO_ = 0;
35 static constexpr uint32_t UINT32_ZERO_ = 0;
36 static constexpr uint32_t UINT32_ONE_ = 1;
37 static constexpr size_t SIZE_TWO_ = 2;
38 static constexpr size_t SIZE_THREE_ = 3;
39
CreateReference(napi_env env)40 napi_ref CreateReference(napi_env env)
41 {
42 napi_value obj = NapiHelper::CreateObject(env);
43 return NapiHelper::CreateReference(env, obj, 1);
44 }
45
CreateSendableClass(napi_env env)46 napi_value SendableUtils::CreateSendableClass(napi_env env)
47 {
48 auto constructor = [](napi_env env, napi_callback_info info) -> napi_value {
49 napi_value thisVar = nullptr;
50 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
51 return thisVar;
52 };
53
54 napi_property_descriptor props[] = {
55 DECLARE_NAPI_FUNCTION("foo", Foo),
56 DECLARE_NAPI_FUNCTION("bar", Bar),
57 };
58
59 napi_value sendableClass = nullptr;
60 napi_define_sendable_class(env, "SendableClass", NAPI_AUTO_LENGTH, constructor, nullptr,
61 sizeof(props) / sizeof(props[0]), props, nullptr, &sendableClass);
62 return sendableClass;
63 }
64
CreateSendableInstance(napi_env env)65 napi_value SendableUtils::CreateSendableInstance(napi_env env)
66 {
67 napi_value cls = SendableUtils::CreateSendableClass(env);
68 napi_value instance = nullptr;
69 napi_new_instance(env, cls, 0, nullptr, &instance);
70 return instance;
71 }
72
Foo(napi_env env,napi_callback_info info)73 napi_value SendableUtils::Foo(napi_env env, napi_callback_info info)
74 {
75 return nullptr;
76 }
77
Bar(napi_env env,napi_callback_info info)78 napi_value SendableUtils::Bar(napi_env env, napi_callback_info info)
79 {
80 return nullptr;
81 }
82
IsConcurrent(napi_env env,napi_value argv[],size_t argc)83 napi_value NativeEngineTest::IsConcurrent(napi_env env, napi_value argv[], size_t argc)
84 {
85 std::string funcName = "IsConcurrent";
86 napi_value cb = nullptr;
87 napi_value result = nullptr;
88 napi_create_function(env, funcName.c_str(), funcName.size(), TaskPool::IsConcurrent, nullptr, &cb);
89 napi_call_function(env, nullptr, cb, argc, argv, &result);
90 return result;
91 }
92
GetTaskPoolInfo(napi_env env,napi_value argv[],size_t argc)93 napi_value NativeEngineTest::GetTaskPoolInfo(napi_env env, napi_value argv[], size_t argc)
94 {
95 std::string funcName = "GetTaskPoolInfo";
96 napi_value cb = nullptr;
97 napi_value result = nullptr;
98 napi_create_function(env, funcName.c_str(), funcName.size(), TaskPool::GetTaskPoolInfo, nullptr, &cb);
99 napi_call_function(env, nullptr, cb, argc, argv, &result);
100 return result;
101 }
102
TerminateTask(napi_env env,napi_value argv[],size_t argc)103 napi_value NativeEngineTest::TerminateTask(napi_env env, napi_value argv[], size_t argc)
104 {
105 std::string funcName = "TerminateTask";
106 napi_value cb = nullptr;
107 napi_value result = nullptr;
108 napi_create_function(env, funcName.c_str(), funcName.size(), TaskPool::TerminateTask, nullptr, &cb);
109 napi_call_function(env, nullptr, cb, argc, argv, &result);
110 return result;
111 }
112
Execute(napi_env env,napi_value argv[],size_t argc)113 napi_value NativeEngineTest::Execute(napi_env env, napi_value argv[], size_t argc)
114 {
115 std::string funcName = "Execute";
116 napi_value cb = nullptr;
117 napi_value result = nullptr;
118 napi_create_function(env, funcName.c_str(), funcName.size(), TaskPool::Execute, nullptr, &cb);
119 napi_call_function(env, nullptr, cb, argc, argv, &result);
120 return result;
121 }
122
ExecuteDelayed(napi_env env,napi_value argv[],size_t argc)123 napi_value NativeEngineTest::ExecuteDelayed(napi_env env, napi_value argv[], size_t argc)
124 {
125 std::string funcName = "ExecuteDelayed";
126 napi_value cb = nullptr;
127 napi_value result = nullptr;
128 napi_create_function(env, funcName.c_str(), funcName.size(), TaskPool::ExecuteDelayed, nullptr, &cb);
129 napi_call_function(env, nullptr, cb, argc, argv, &result);
130 return result;
131 }
132
Cancel(napi_env env,napi_value argv[],size_t argc)133 napi_value NativeEngineTest::Cancel(napi_env env, napi_value argv[], size_t argc)
134 {
135 std::string funcName = "Cancel";
136 napi_value cb = nullptr;
137 napi_value result = nullptr;
138 napi_create_function(env, funcName.c_str(), funcName.size(), TaskPool::Cancel, nullptr, &cb);
139 napi_call_function(env, nullptr, cb, argc, argv, &result);
140 return result;
141 }
142
TaskGroupDestructor(napi_env env,void * data)143 void NativeEngineTest::TaskGroupDestructor(napi_env env, void* data)
144 {
145 void* hint = nullptr;
146 TaskGroup::TaskGroupDestructor(env, data, hint);
147 }
148
SequenceRunnerDestructor(napi_env env,void * data)149 void NativeEngineTest::SequenceRunnerDestructor(napi_env env, void* data)
150 {
151 void* hint = nullptr;
152 SequenceRunner::SequenceRunnerDestructor(env, data, hint);
153 }
154
ExecutePeriodically(napi_env env,napi_value argv[],size_t argc)155 napi_value NativeEngineTest::ExecutePeriodically(napi_env env, napi_value argv[], size_t argc)
156 {
157 std::string funcName = "ExecutePeriodically";
158 napi_value cb = nullptr;
159 napi_value result = nullptr;
160 napi_create_function(env, funcName.c_str(), funcName.size(), TaskPool::ExecutePeriodically, nullptr, &cb);
161 napi_call_function(env, nullptr, cb, argc, argv, &result);
162 return result;
163 }
164
ExecuteGroup(napi_env env,napi_value taskGroup)165 napi_value NativeEngineTest::ExecuteGroup(napi_env env, napi_value taskGroup)
166 {
167 return TaskPool::ExecuteGroup(env, taskGroup, Priority::DEFAULT);
168 }
169
DelayTask(uv_timer_t * handle)170 void NativeEngineTest::DelayTask(uv_timer_t* handle)
171 {
172 TaskPool::DelayTask(handle);
173 }
174
PeriodicTaskCallback(uv_timer_t * handle)175 void NativeEngineTest::PeriodicTaskCallback(uv_timer_t* handle)
176 {
177 TaskPool::PeriodicTaskCallback(handle);
178 }
179
UpdateGroupInfoByResult(napi_env env,uv_timer_t * handle,napi_value res,bool success)180 void NativeEngineTest::UpdateGroupInfoByResult(napi_env env, uv_timer_t* handle, napi_value res, bool success)
181 {
182 Task* task = reinterpret_cast<Task*>(handle->data);
183 TaskPool::UpdateGroupInfoByResult(env, task, res, success);
184 }
185
TryTriggerExpand()186 void NativeEngineTest::TryTriggerExpand()
187 {
188 TaskManager& taskManager = TaskManager::GetInstance();
189 taskManager.isHandleInited_ = false;
190 taskManager.TryTriggerExpand();
191 taskManager.isHandleInited_ = true;
192 taskManager.needChecking_ = false;
193 }
194
CheckForBlockedWorkers(napi_env env)195 void NativeEngineTest::CheckForBlockedWorkers(napi_env env)
196 {
197 Worker* worker = reinterpret_cast<Worker*>(WorkerConstructor(env));
198 worker->workerEnv_ = nullptr;
199 TaskManager& taskManager = TaskManager::GetInstance();
200 taskManager.workers_.clear();
201 taskManager.workers_.insert(worker);
202 taskManager.GetThreadInfos(env);
203
204 worker->workerEnv_ = env;
205 worker->state_ = WorkerState::RUNNING;
206 worker->startTime_ = ConcurrentHelper::GetMilliseconds() - MAX_TIMEOUT_TIME;
207 worker->idleState_ = true;
208 taskManager.CheckForBlockedWorkers();
209
210 worker->state_ = WorkerState::RUNNING;
211 worker->startTime_ = ConcurrentHelper::GetMilliseconds() - MAX_TIMEOUT_TIME;
212 worker->idleState_ = false;
213 worker->hasLongTask_ = true;
214 taskManager.CheckForBlockedWorkers();
215
216 worker->state_ = WorkerState::RUNNING;
217 worker->startTime_ = ConcurrentHelper::GetMilliseconds() - MAX_TIMEOUT_TIME;
218 worker->idleState_ = false;
219 worker->hasLongTask_ = false;
220 taskManager.idleWorkers_.insert(worker);
221 taskManager.CheckForBlockedWorkers();
222 taskManager.timeoutWorkers_.clear();
223 }
224
foo(const uv_async_t * req)225 void NativeEngineTest::foo(const uv_async_t* req)
226 {
227 return;
228 }
229
TriggerShrink(napi_env env)230 void NativeEngineTest::TriggerShrink(napi_env env)
231 {
232 uint32_t step = 1;
233 TaskManager& taskManager = TaskManager::GetInstance();
234 taskManager.idleWorkers_.clear();
235 Worker* worker = reinterpret_cast<Worker*>(WorkerConstructor(env));
236 worker->workerEnv_ = env;
237 taskManager.idleWorkers_.insert(worker);
238
239 taskManager.freeList_.emplace_back(worker);
240 worker->state_ = WorkerState::RUNNING;
241 taskManager.TriggerShrink(step);
242
243 taskManager.idleWorkers_.clear();
244 taskManager.idleWorkers_.insert(worker);
245 taskManager.freeList_.emplace_back(worker);
246 worker->idlePoint_ = ConcurrentHelper::GetMilliseconds();
247 worker->state_ = WorkerState::IDLE;
248 worker->hasLongTask_ = false;
249 taskManager.TriggerShrink(step);
250
251 taskManager.idleWorkers_.clear();
252 taskManager.idleWorkers_.insert(worker);
253 taskManager.freeList_.emplace_back(worker);
254 worker->idlePoint_ = ConcurrentHelper::GetMilliseconds() - MAX_TIMEOUT_TIME;
255 worker->state_ = WorkerState::IDLE;
256 worker->hasLongTask_ = false;
257 uv_loop_t* loop = worker->GetWorkerLoop();
258 ConcurrentHelper::UvHandleInit(loop, worker->clearWorkerSignal_, NativeEngineTest::foo, worker);
259 taskManager.TriggerShrink(step);
260 taskManager.idleWorkers_.clear();
261 taskManager.globalEnableFfrtFlag_ = false;
262 }
263
NotifyShrink(napi_env env)264 void NativeEngineTest::NotifyShrink(napi_env env)
265 {
266 uint32_t step = 1;
267 TaskManager& taskManager = TaskManager::GetInstance();
268 taskManager.workers_.clear();
269 taskManager.timeoutWorkers_.clear();
270
271 Worker* worker1 = reinterpret_cast<Worker*>(WorkerConstructor(env));
272 Worker* worker2 = reinterpret_cast<Worker*>(WorkerConstructor(env));
273 worker1->workerEnv_ = env;
274 worker2->workerEnv_ = env;
275 uv_loop_t* loop1 = worker1->GetWorkerLoop();
276 ConcurrentHelper::UvHandleInit(loop1, worker1->clearWorkerSignal_, NativeEngineTest::foo, worker1);
277 uv_loop_t* loop2 = worker2->GetWorkerLoop();
278 ConcurrentHelper::UvHandleInit(loop2, worker2->clearWorkerSignal_, NativeEngineTest::foo, worker2);
279 taskManager.workers_.insert(worker1);
280 taskManager.workers_.insert(worker2);
281 taskManager.timeoutWorkers_.insert(worker1);
282 taskManager.timeoutWorkers_.insert(worker2);
283 taskManager.NotifyShrink(step);
284
285 taskManager.workers_.clear();
286 taskManager.timeoutWorkers_.clear();
287 taskManager.workers_.insert(worker1);
288 taskManager.idleWorkers_.insert(nullptr);
289 taskManager.NotifyShrink(step);
290
291 taskManager.idleWorkers_.clear();
292 taskManager.idleWorkers_.insert(worker2);
293 worker2->hasLongTask_ = true;
294 taskManager.NotifyShrink(step);
295
296 worker2->hasLongTask_ = false;
297 worker2->hasExecuted_ = true;
298 taskManager.NotifyShrink(step);
299
300 worker2->hasExecuted_ = false;
301 taskManager.workers_.clear();
302 taskManager.NotifyShrink(step);
303 }
304
TryExpand(napi_env env)305 void NativeEngineTest::TryExpand(napi_env env)
306 {
307 TaskManager& taskManager = TaskManager::GetInstance();
308 taskManager.workers_.clear();
309 taskManager.timeoutWorkers_.clear();
310 taskManager.idleWorkers_.clear();
311 Worker* worker = reinterpret_cast<Worker*>(WorkerConstructor(env));
312 worker->workerEnv_ = env;
313 uv_loop_t* loop = worker->GetWorkerLoop();
314 ConcurrentHelper::UvHandleInit(loop, worker->performTaskSignal_, NativeEngineTest::foo, worker);
315 taskManager.idleWorkers_.insert(worker);
316 taskManager.TryExpand();
317 taskManager.nonIdleTaskNum_ = 1;
318 taskManager.TryExpand();
319 taskManager.nonIdleTaskNum_ = 0;
320 taskManager.TryExpand();
321 taskManager.idleWorkers_.clear();
322 taskManager.suspend_ = true;
323 taskManager.TryExpand();
324 }
325
CancelTask(napi_env env)326 void NativeEngineTest::CancelTask(napi_env env)
327 {
328 TaskManager& taskManager = TaskManager::GetInstance();
329 Task* task = new Task();
330 task->taskType_ = TaskType::COMMON_TASK;
331 task->taskId_ = reinterpret_cast<uint64_t>(task);
332 napi_value val = NapiHelper::CreateObject(env);
333 napi_ref ref = NapiHelper::CreateReference(env, val, 0);
334 task->taskRef_ = ref;
335 taskManager.StoreTask(task->taskId_, task);
336 task->taskState_ = ExecuteState::CANCELED;
337 taskManager.CancelTask(env, task->taskId_);
338
339 uv_loop_t* loop = NapiHelper::GetLibUV(env);
340 task->timer_ = new uv_timer_t;
341 uv_timer_init(loop, task->timer_);
342 task->taskState_ = ExecuteState::RUNNING;
343 task->isPeriodicTask_ = true;
344 taskManager.CancelTask(env, task->taskId_);
345
346 task->isPeriodicTask_ = false;
347 task->taskType_ = TaskType::SEQRUNNER_TASK;
348 taskManager.CancelTask(env, task->taskId_);
349
350 task->taskState_ = ExecuteState::FINISHED;
351 taskManager.CancelTask(env, task->taskId_);
352
353 TaskInfo* taskInfo = new TaskInfo();
354 task->taskState_ = ExecuteState::WAITING;
355 task->currentTaskInfo_ = taskInfo;
356 taskManager.CancelTask(env, task->taskId_);
357 taskManager.tasks_.clear();
358 delete task;
359 }
360
NotifyWorkerIdle(napi_env env)361 void NativeEngineTest::NotifyWorkerIdle(napi_env env)
362 {
363 TaskManager& taskManager = TaskManager::GetInstance();
364 Task* task = new Task();
365 task->taskId_ = reinterpret_cast<uint64_t>(task);
366 taskManager.taskQueues_[Priority::DEFAULT]->EnqueueTaskId(task->taskId_);
367 Worker* worker = reinterpret_cast<Worker*>(WorkerConstructor(env));
368 worker->workerEnv_ = env;
369 uv_loop_t* loop = worker->GetWorkerLoop();
370 ConcurrentHelper::UvHandleInit(loop, worker->performTaskSignal_, NativeEngineTest::foo, worker);
371 worker->state_ = WorkerState::BLOCKED;
372 taskManager.NotifyWorkerIdle(worker);
373 worker->state_ = WorkerState::IDLE;
374 taskManager.NotifyWorkerIdle(worker);
375 delete task;
376 }
377
EnqueueTaskId(napi_env env)378 void NativeEngineTest::EnqueueTaskId(napi_env env)
379 {
380 TaskManager& taskManager = TaskManager::GetInstance();
381 Task* task = new Task();
382 task->taskId_ = reinterpret_cast<uint64_t>(task);
383 taskManager.StoreTask(task->taskId_, task);
384 napi_value obj = Helper::NapiHelper::CreateObject(env);
385 napi_ref callbackRef = Helper::NapiHelper::CreateReference(env, obj, 1);
386 task->onEnqueuedCallBackInfo_ = new ListenerCallBackInfo(env, callbackRef, nullptr);
387 taskManager.EnqueueTaskId(task->taskId_);
388
389 taskManager.workers_.clear();
390 Worker* worker = reinterpret_cast<Worker*>(WorkerConstructor(env));
391 worker->state_ = WorkerState::RUNNING;
392 taskManager.workers_.insert(worker);
393 taskManager.IsChooseIdle();
394 taskManager.workers_.clear();
395 Helper::NapiHelper::DeleteReference(env, callbackRef);
396 delete task;
397 }
398
GetTaskByPriority(napi_env env)399 void NativeEngineTest::GetTaskByPriority(napi_env env)
400 {
401 TaskManager& taskManager = TaskManager::GetInstance();
402 Task* task = new Task();
403 task->taskId_ = reinterpret_cast<uint64_t>(task);
404 taskManager.StoreTask(task->taskId_, task);
405 auto& mediumTaskQueue = taskManager.taskQueues_[Priority::DEFAULT];
406 uint64_t id = mediumTaskQueue->DequeueTaskId();
407 while (id != 0) {
408 id = mediumTaskQueue->DequeueTaskId();
409 }
410 taskManager.EnqueueTaskId(task->taskId_);
411 std::set<uint64_t> set{task->taskId_};
412 taskManager.dependTaskInfos_.emplace(task->taskId_, std::move(set));
413 taskManager.GetTaskByPriority(mediumTaskQueue, Priority::DEFAULT);
414 taskManager.dependTaskInfos_.clear();
415 taskManager.tasks_.clear();
416 delete task;
417 }
418
RestoreWorker(napi_env env)419 void NativeEngineTest::RestoreWorker(napi_env env)
420 {
421 TaskManager& taskManager = TaskManager::GetInstance();
422 Worker* worker = reinterpret_cast<Worker*>(WorkerConstructor(env));
423 taskManager.suspend_ = false;
424 worker->state_ = WorkerState::BLOCKED;
425 taskManager.RestoreWorker(worker);
426
427 Task* task = new Task();
428 task->taskId_ = reinterpret_cast<uint64_t>(task);
429 taskManager.EnqueueTaskId(task->taskId_);
430 worker->state_ = WorkerState::IDLE;
431 worker->workerEnv_ = env;
432 uv_loop_t* loop = worker->GetWorkerLoop();
433 ConcurrentHelper::UvHandleInit(loop, worker->performTaskSignal_, NativeEngineTest::foo, worker);
434 taskManager.RestoreWorker(worker);
435 }
436
StoreDependentId(uint64_t taskId,uint64_t dependentId)437 void NativeEngineTest::StoreDependentId(uint64_t taskId, uint64_t dependentId)
438 {
439 TaskManager& taskManager = TaskManager::GetInstance();
440 std::set<uint64_t> set{ dependentId };
441 taskManager.dependTaskInfos_.emplace(taskId, std::move(set));
442 }
443
StoreDependentTaskId(uint64_t taskId,uint64_t dependentId)444 void NativeEngineTest::StoreDependentTaskId(uint64_t taskId, uint64_t dependentId)
445 {
446 TaskManager& taskManager = TaskManager::GetInstance();
447 std::set<uint64_t> set{ dependentId };
448 taskManager.dependentTaskInfos_.emplace(taskId, std::move(set));
449 }
450
StoreTaskDuration(uint64_t taskId)451 void NativeEngineTest::StoreTaskDuration(uint64_t taskId)
452 {
453 TaskManager& taskManager = TaskManager::GetInstance();
454 uint64_t durationId = taskId + MAX_TIMEOUT_TIME;
455 std::pair<uint64_t, uint64_t> durationData = std::make_pair(taskId, durationId);
456 taskManager.taskDurationInfos_.emplace(taskId, std::move(durationData));
457 }
458
InitTaskManager(napi_env env)459 void NativeEngineTest::InitTaskManager(napi_env env)
460 {
461 napi_env taskEnv = nullptr;
462 napi_create_runtime(env, &taskEnv);
463 NativeEngine* taskEngine = reinterpret_cast<NativeEngine*>(taskEnv);
464 taskEngine->MarkTaskPoolThread();
465 TaskManager& taskManager = TaskManager::GetInstance();
466 taskManager.globalEnableFfrtFlag_ = true;
467 taskManager.InitTaskManager(taskEnv);
468 taskManager.DecreaseRefCount(env, 0);
469 napi_value exception = nullptr;
470 napi_get_and_clear_last_exception(env, &exception);
471 }
472
NotifyDependencyTaskInfo(napi_env env)473 void NativeEngineTest::NotifyDependencyTaskInfo(napi_env env)
474 {
475 TaskManager& taskManager = TaskManager::GetInstance();
476 Task* task = new Task();
477 task->taskId_ = reinterpret_cast<uint64_t>(task);
478 task->env_ = env;
479 Worker* worker = reinterpret_cast<Worker*>(WorkerConstructor(env));
480 worker->workerEnv_ = env;
481 task->worker_ = worker;
482 uint64_t id = task->taskId_ + MAX_TIMEOUT_TIME;
483 std::set<uint64_t> set{ task->taskId_, id };
484 taskManager.dependentTaskInfos_.emplace(task->taskId_, std::move(set));
485 taskManager.NotifyDependencyTaskInfo(task->taskId_);
486 std::set<uint64_t> set1{ task->taskId_, id };
487 taskManager.dependentTaskInfos_.emplace(task->taskId_, std::move(set1));
488 taskManager.EnqueuePendingTaskInfo(0, Priority::DEFAULT);
489 taskManager.EnqueuePendingTaskInfo(id, Priority::DEFAULT);
490 taskManager.EnqueuePendingTaskInfo(task->taskId_, Priority::DEFAULT);
491 taskManager.NotifyDependencyTaskInfo(task->taskId_);
492 std::set<uint64_t> set2{ task->taskId_, id };
493 taskManager.dependentTaskInfos_.emplace(task->taskId_, std::move(set2));
494 taskManager.IsDependentByTaskId(task->taskId_);
495 }
496
StoreTaskDependency(napi_env env)497 void NativeEngineTest::StoreTaskDependency(napi_env env)
498 {
499 TaskManager& taskManager = TaskManager::GetInstance();
500 Task* task = new Task();
501 task->taskId_ = reinterpret_cast<uint64_t>(task);
502 task->env_ = env;
503 Task* task1 = new Task();
504 task1->taskId_ = reinterpret_cast<uint64_t>(task1);
505 task1->env_ = env;
506 Task* task2 = new Task();
507 task2->taskId_ = reinterpret_cast<uint64_t>(task1);
508 task2->env_ = env;
509 taskManager.dependTaskInfos_.clear();
510 uint64_t id1 = task->taskId_;
511 uint64_t id2 = task->taskId_ + MAX_TIMEOUT_TIME;
512 uint64_t id3 = task1->taskId_;
513 uint64_t id4 = task1->taskId_ + MAX_TIMEOUT_TIME;
514 uint64_t id5 = task2->taskId_;
515 uint64_t id6 = task2->taskId_ + MAX_TIMEOUT_TIME;
516 std::set<uint64_t> set{ id2, id3 };
517 taskManager.dependTaskInfos_.emplace(id1, std::move(set));
518 std::set<uint64_t> taskId{ id1, id2 };
519 taskManager.StoreTaskDependency(id3, taskId);
520 taskManager.StoreTaskDependency(id5, taskId);
521 std::set<uint64_t> set1{ id4, id5 };
522 taskManager.dependTaskInfos_.emplace(id3, std::move(set1));
523 taskManager.StoreTaskDependency(id1, taskId);
524 std::set<uint64_t> set2{ id6 };
525 std::set<uint64_t> set3{ id1 };
526 taskManager.dependTaskInfos_.emplace(id5, std::move(set3));
527 taskManager.StoreTaskDependency(id1, taskId);
528 taskManager.dependTaskInfos_.emplace(id5, std::move(set2));
529 taskManager.StoreTaskDependency(id1, taskId);
530 taskManager.dependTaskInfos_.clear();
531 napi_value exception = nullptr;
532 napi_get_and_clear_last_exception(env, &exception);
533 }
534
RemoveTaskDependency(napi_env env)535 void NativeEngineTest::RemoveTaskDependency(napi_env env)
536 {
537 TaskManager& taskManager = TaskManager::GetInstance();
538 Task* task = new Task();
539 task->taskId_ = reinterpret_cast<uint64_t>(task);
540 uint64_t id = task->taskId_ + MAX_TIMEOUT_TIME;
541 Task* task1 = new Task();
542 task1->taskId_ = reinterpret_cast<uint64_t>(task1);
543 uint64_t id2 = task1->taskId_ + MAX_TIMEOUT_TIME;
544 taskManager.dependTaskInfos_.clear();
545 std::set<uint64_t> set{ id };
546 taskManager.dependTaskInfos_.emplace(task->taskId_, std::move(set));
547 taskManager.RemoveTaskDependency(task->taskId_, task1->taskId_);
548 taskManager.RemoveTaskDependency(task->taskId_, id);
549 std::set<uint64_t> set2{ id };
550 taskManager.dependentTaskInfos_.emplace(task->taskId_, std::move(set2));
551 std::set<uint64_t> dependentTaskIdSet{ task->taskId_ };
552 taskManager.StoreDependentTaskInfo(dependentTaskIdSet, task1->taskId_);
553 taskManager.RemoveDependentTaskInfo(task->taskId_, id2);
554 taskManager.RemoveDependentTaskInfo(task->taskId_, id);
555 taskManager.GetTaskDependInfoToString(task1->taskId_);
556 taskManager.taskDurationInfos_.emplace(task->taskId_, std::make_pair(UINT64_ZERO_, task1->taskId_));
557 taskManager.StoreTaskDuration(task->taskId_, UINT64_ZERO_, UINT64_ZERO_);
558 taskManager.GetTaskDuration(task->taskId_, "");
559 taskManager.RemoveTaskDuration(task->taskId_);
560 }
561
ReleaseTaskData(napi_env env)562 void NativeEngineTest::ReleaseTaskData(napi_env env)
563 {
564 TaskManager& taskManager = TaskManager::GetInstance();
565 Task* task = new Task();
566 task->taskId_ = reinterpret_cast<uint64_t>(task);
567 task->onResultSignal_ = nullptr;
568 task->taskType_ = TaskType::FUNCTION_TASK;
569 taskManager.StoreTask(task->taskId_, task);
570 taskManager.ReleaseTaskData(env, task);
571 task->taskType_ = TaskType::GROUP_FUNCTION_TASK;
572 taskManager.StoreTask(task->taskId_, task);
573 taskManager.ReleaseTaskData(env, task);
574 std::set<uint64_t> set{ task->taskId_ };
575 taskManager.dependTaskInfos_.emplace(task->taskId_, std::move(set));
576 task->taskType_ = TaskType::COMMON_TASK;
577 taskManager.StoreTask(task->taskId_, task);
578 taskManager.ReleaseTaskData(env, task);
579 Task* task1 = new Task();
580 task1->taskId_ = reinterpret_cast<uint64_t>(task1);
581 task1->onEnqueuedCallBackInfo_ = new ListenerCallBackInfo(env, nullptr, nullptr);
582 task1->onStartExecutionCallBackInfo_ = new ListenerCallBackInfo(env, nullptr, nullptr);
583 task1->onExecutionFailedCallBackInfo_ = new ListenerCallBackInfo(env, nullptr, nullptr);
584 task1->onExecutionSucceededCallBackInfo_ = new ListenerCallBackInfo(env, nullptr, nullptr);
585 taskManager.ReleaseCallBackInfo(task1);
586 Task* task2 = new Task();
587 task2->taskId_ = reinterpret_cast<uint64_t>(task2);
588 task2->isMainThreadTask_ = true;
589 taskManager.ReleaseCallBackInfo(task2);
590 task2->isMainThreadTask_ = false;
591 taskManager.ReleaseCallBackInfo(task2);
592 auto loop = NapiHelper::GetLibUV(env);
593 ConcurrentHelper::UvHandleInit(loop, task->onStartExecutionSignal_, NativeEngineTest::foo, task2);
594 taskManager.ReleaseCallBackInfo(task2);
595 }
596
CheckTask(napi_env env)597 void NativeEngineTest::CheckTask(napi_env env)
598 {
599 TaskManager& taskManager = TaskManager::GetInstance();
600 Task* task = new Task();
601 task->taskId_ = reinterpret_cast<uint64_t>(task);
602 Task* task1 = new Task();
603 task1->taskId_ = reinterpret_cast<uint64_t>(task1);
604 taskManager.StoreTask(task->taskId_, task);
605 taskManager.CheckTask(task1->taskId_);
606
607 TaskGroupManager& groupManager = TaskGroupManager::GetInstance();
608 TaskGroup* group = new TaskGroup();
609 napi_value obj = NapiHelper::CreateObject(env);
610 napi_ref ref = NapiHelper::CreateReference(env, obj, 1);
611 group->groupRef_ = ref;
612 uint64_t groupId = reinterpret_cast<uint64_t>(group);
613 groupManager.StoreTaskGroup(groupId, nullptr);
614 groupManager.AddTask(groupId, nullptr, task->taskId_);
615 groupManager.taskGroups_.clear();
616 groupManager.StoreTaskGroup(groupId, group);
617 group->groupState_ = ExecuteState::CANCELED;
618 groupManager.CancelGroup(env, groupId);
619
620 group->groupState_ = ExecuteState::WAITING;
621 groupManager.CancelGroup(env, groupId);
622
623 GroupInfo* groupInfo = new GroupInfo();
624 groupInfo->finishedTaskNum = FINSHED_TASK_;
625 group->currentGroupInfo_ = groupInfo;
626 group->groupState_ = ExecuteState::NOT_FOUND;
627 groupManager.CancelGroup(env, groupId);
628
629 group->groupState_ = ExecuteState::FINISHED;
630 groupManager.CancelGroup(env, groupId);
631
632 group->groupState_ = ExecuteState::RUNNING;
633 group->taskNum_ = FINSHED_TASK_;
634 group->taskIds_.push_back(task->taskId_);
635 groupManager.CancelGroup(env, groupId);
636
637 group->taskNum_ = TASK_NUMS_;
638 group->groupState_ = ExecuteState::WAITING;
639 napi_value resArr;
640 napi_create_array_with_length(env, group->taskIds_.size(), &resArr);
641 napi_ref arrRef = NapiHelper::CreateReference(env, resArr, 1);
642 groupInfo->resArr = arrRef;
643 napi_value promise = NapiHelper::CreatePromise(env, &groupInfo->deferred);
644 groupManager.CancelGroup(env, groupId);
645 }
646
CancelGroupTask(napi_env env)647 void NativeEngineTest::CancelGroupTask(napi_env env)
648 {
649 TaskGroupManager& groupManager = TaskGroupManager::GetInstance();
650 TaskManager& taskManager = TaskManager::GetInstance();
651 TaskGroup* group = new TaskGroup();
652 group->currentGroupInfo_ = new GroupInfo();
653 Task* task = new Task();
654 task->taskId_ = reinterpret_cast<uint64_t>(task);
655 taskManager.StoreTask(task->taskId_, task);
656 task->taskState_ = ExecuteState::RUNNING;
657 groupManager.CancelGroupTask(env, task->taskId_, group);
658 task->taskState_ = ExecuteState::WAITING;
659 groupManager.CancelGroupTask(env, task->taskId_, group);
660 task->taskState_ = ExecuteState::WAITING;
661 TaskInfo* taskInfo = new TaskInfo();
662 task->currentTaskInfo_ = taskInfo;
663 groupManager.CancelGroupTask(env, task->taskId_, group);
664
665 Task* task1 = new Task();
666 task1->taskId_ = reinterpret_cast<uint64_t>(task1);
667 SequenceRunner* seqRunner = new SequenceRunner();
668 uint64_t seqRunnerId = reinterpret_cast<uint64_t>(seqRunner);
669 groupManager.StoreSequenceRunner(seqRunnerId, seqRunner);
670 groupManager.AddTaskToSeqRunner(seqRunnerId, task1);
671 }
672
TriggerSeqRunner(napi_env env)673 void NativeEngineTest::TriggerSeqRunner(napi_env env)
674 {
675 TaskGroupManager& groupManager = TaskGroupManager::GetInstance();
676 Task* task = new Task();
677 task->taskId_ = reinterpret_cast<uint64_t>(task);
678 Task* task1 = new Task();
679 task1->taskId_ = reinterpret_cast<uint64_t>(task1);
680 SequenceRunner* seqRunner = new SequenceRunner();
681 uint64_t seqRunnerId = reinterpret_cast<uint64_t>(seqRunner);
682 seqRunner->priority_ = Priority::DEFAULT;
683 task->seqRunnerId_ = seqRunnerId;
684 groupManager.StoreSequenceRunner(seqRunnerId, seqRunner);
685 seqRunner->isGlobalRunner_ = true;
686 bool res = groupManager.TriggerSeqRunner(env, task);
687 ASSERT_FALSE(res);
688 seqRunner->globalSeqRunnerRef_.emplace(env, CreateReference(env));
689 seqRunner->currentTaskId_ = task1->taskId_;
690 groupManager.TriggerSeqRunner(env, task);
691 seqRunner->isGlobalRunner_ = false;
692 seqRunner->seqRunnerRef_ = CreateReference(env);
693 seqRunner->currentTaskId_ = task->taskId_;
694 groupManager.TriggerSeqRunner(env, task);
695 seqRunner->seqRunnerRef_ = CreateReference(env);
696 task1->taskState_ = ExecuteState::CANCELED;
697 seqRunner->seqRunnerTasks_.push(task1);
698 TaskInfo* taskInfo = new TaskInfo();
699 task1->currentTaskInfo_ = taskInfo;
700 seqRunner->currentTaskId_ = task->taskId_;
701 groupManager.TriggerSeqRunner(env, task);
702 seqRunner->seqRunnerRef_ = CreateReference(env);
703 TaskInfo* taskInfo1 = new TaskInfo();
704 task1->currentTaskInfo_ = taskInfo1;
705 seqRunner->seqRunnerTasks_.push(task1);
706 seqRunner->seqRunnerTasks_.push(task);
707 task->taskState_ = ExecuteState::RUNNING;
708 seqRunner->currentTaskId_ = task->taskId_;
709 groupManager.TriggerSeqRunner(env, task);
710 }
711
UpdateGroupState(napi_env env)712 void NativeEngineTest::UpdateGroupState(napi_env env)
713 {
714 TaskGroupManager& groupManager = TaskGroupManager::GetInstance();
715 TaskGroup* group = new TaskGroup();
716 uint64_t groupId = reinterpret_cast<uint64_t>(group);
717 Task* task = new Task();
718 task->taskId_ = reinterpret_cast<uint64_t>(task);
719 groupManager.StoreTaskGroup(groupId, group);
720 groupManager.UpdateGroupState(task->taskId_);
721 group->groupState_ = ExecuteState::CANCELED;
722 groupManager.UpdateGroupState(groupId);
723 group->groupState_ = ExecuteState::WAITING;
724 groupManager.UpdateGroupState(groupId);
725
726 SequenceRunnerManager& runnerManager = SequenceRunnerManager::GetInstance();
727 napi_value obj = NapiHelper::CreateObject(env);
728 SequenceRunner* seqRunner = runnerManager.CreateOrGetGlobalRunner(env, obj, SIZE_THREE_, "test", UINT32_ONE_);
729 seqRunner->priority_ = Priority::MEDIUM;
730 runnerManager.CreateOrGetGlobalRunner(env, obj, SIZE_TWO_, "test", UINT32_ZERO_);
731 runnerManager.CreateOrGetGlobalRunner(env, obj, SIZE_TWO_, "test", UINT32_ONE_);
732 runnerManager.DecreaseSeqCount(seqRunner);
733 runnerManager.RemoveGlobalSeqRunnerRef(env, seqRunner);
734 runnerManager.RemoveSequenceRunner("func");
735 runnerManager.RemoveSequenceRunner("test");
736 }
737
ReleaseWorkerHandles(napi_env env)738 void NativeEngineTest::ReleaseWorkerHandles(napi_env env)
739 {
740 ExceptionScope scope(env);
741 Worker* worker = reinterpret_cast<Worker*>(WorkerConstructor(env));
742 napi_env workerEnv = nullptr;
743 napi_create_runtime(env, &workerEnv);
744 worker->workerEnv_ = workerEnv;
745 NativeEngine* workerEngine = reinterpret_cast<NativeEngine*>(workerEnv);
746 uv_loop_t* loop = worker->GetWorkerLoop();
747 ConcurrentHelper::UvHandleInit(loop, worker->performTaskSignal_,
748 NativeEngineTest::foo, worker);
749 ConcurrentHelper::UvHandleInit(loop, worker->debuggerOnPostTaskSignal_,
750 NativeEngineTest::foo, worker);
751 ConcurrentHelper::UvHandleInit(loop, worker->clearWorkerSignal_,
752 NativeEngineTest::foo, worker);
753 uv_async_t* req = new uv_async_t;
754 req->data = worker;
755 Worker::ReleaseWorkerHandles(req);
756 }
757
DebuggerOnPostTask(napi_env env)758 void NativeEngineTest::DebuggerOnPostTask(napi_env env)
759 {
760 ExceptionScope scope(env);
761 Worker* worker = reinterpret_cast<Worker*>(WorkerConstructor(env));
762 uv_loop_t* loop = worker->GetWorkerLoop();
763 ConcurrentHelper::UvHandleInit(loop, worker->debuggerOnPostTaskSignal_,
764 NativeEngineTest::foo, worker);
765 std::function<void()> myTask = []() {
766 return;
767 };
768 worker->DebuggerOnPostTask(std::move(myTask));
769 uv_async_t* req = new uv_async_t;
770 std::function<void()> myTask1 = []() {
771 return;
772 };
773 worker->debuggerQueue_.push(myTask1);
774 req->data = worker;
775 worker->debuggerMutex_.unlock();
776 Worker::HandleDebuggerTask(req);
777 worker->workerEnv_ = nullptr;
778 worker->ReleaseWorkerThreadContent();
779 napi_env workerEnv = nullptr;
780 napi_create_runtime(env, &workerEnv);
781 worker->workerEnv_ = workerEnv;
782 worker->hostEnv_ = nullptr;
783 worker->state_ = WorkerState::BLOCKED;
784 worker->ReleaseWorkerThreadContent();
785 napi_env workerEnv1 = nullptr;
786 napi_create_runtime(env, &workerEnv1);
787 worker->hostEnv_ = env;
788 worker->workerEnv_ = workerEnv1;
789 worker->state_ = WorkerState::IDLE;
790 worker->ReleaseWorkerThreadContent();
791 }
792
PerformTask(napi_env env)793 void NativeEngineTest::PerformTask(napi_env env)
794 {
795 ExceptionScope scope(env);
796 TaskManager& taskManager = TaskManager::GetInstance();
797 Worker* worker = reinterpret_cast<Worker*>(WorkerConstructor(env));
798 napi_env workerEnv = nullptr;
799 napi_create_runtime(env, &workerEnv);
800 worker->workerEnv_ = workerEnv;
801
802 TaskGroup* group = new TaskGroup();
803 uint64_t groupId = reinterpret_cast<uint64_t>(group);
804 group->groupState_ = ExecuteState::WAITING;
805 TaskGroupManager& groupManager = TaskGroupManager::GetInstance();
806 groupManager.StoreTaskGroup(groupId, group);
807
808 Task* task = new Task();
809 task->taskId_ = reinterpret_cast<uint64_t>(task);
810 taskManager.StoreTask(task->taskId_, task);
811 Priority priority = Priority::DEFAULT;
812 auto& mediumTaskQueue = taskManager.taskQueues_[priority];
813 uint64_t id = mediumTaskQueue->DequeueTaskId();
814 while (id != 0) {
815 id = mediumTaskQueue->DequeueTaskId();
816 }
817 mediumTaskQueue->EnqueueTaskId(task->taskId_);
818
819 uv_async_t* req = new uv_async_t;
820 req->data = worker;
821 task->taskState_ = ExecuteState::WAITING;
822 task->taskType_ = TaskType::GROUP_COMMON_TASK;
823 task->groupId_ = groupId;
824 Worker::PerformTask(req);
825 usleep(100000); // 100000: is sleep 100ms
826 }
827
NotifyHandleTaskResult(napi_env env)828 void NativeEngineTest::NotifyHandleTaskResult(napi_env env)
829 {
830 ExceptionScope scope(env);
831 Worker* worker = reinterpret_cast<Worker*>(WorkerConstructor(env));
832 Task* task = new Task();
833 task->taskId_ = reinterpret_cast<uint64_t>(task);
834 task->env_ = worker->workerEnv_;
835 uv_loop_t* loop = worker->GetWorkerLoop();
836 ConcurrentHelper::UvHandleInit(loop, task->onResultSignal_, NativeEngineTest::foo, task);
837 Task* task1 = new Task();
838 task1->taskId_ = reinterpret_cast<uint64_t>(task1);
839 worker->currentTaskId_.push_back(task1->taskId_);
840 task->worker_ = worker;
841 task->isMainThreadTask_ = true;
842 task->taskRefCount_.fetch_add(1);
843 TaskManager::GetInstance().StoreTask(task->taskId_, task);
844 Worker::NotifyHandleTaskResult(task);
845 }
846
TaskResultCallback(napi_env env)847 void NativeEngineTest::TaskResultCallback(napi_env env)
848 {
849 ExceptionScope scope(env);
850 Worker* worker = reinterpret_cast<Worker*>(WorkerConstructor(env));
851 Task* task = new Task();
852 task->taskId_ = reinterpret_cast<uint64_t>(task);
853 task->env_ = worker->workerEnv_;
854 task->taskRefCount_.fetch_add(1);
855 task->worker_ = worker;
856 task->cpuTime_ = UINT64_ZERO_;
857 Worker::TaskResultCallback(worker->workerEnv_, nullptr, false, reinterpret_cast<void*>(task));
858 task->taskRefCount_.fetch_add(1);
859 task->cpuTime_ = task->taskId_;
860 Worker::TaskResultCallback(worker->workerEnv_, nullptr, true, reinterpret_cast<void*>(task));
861
862 worker->priority_ = Priority::LOW;
863 worker->ResetWorkerPriority();
864 TaskManager& taskManager = TaskManager::GetInstance();
865 taskManager.globalEnableFfrtFlag_ = true;
866 worker->priority_ = Priority::HIGH;
867 worker->ResetWorkerPriority();
868 taskManager.globalEnableFfrtFlag_ = false;
869 worker->state_ = WorkerState::BLOCKED;
870 worker->UpdateExecutedInfo();
871 worker->state_ = WorkerState::IDLE;
872 worker->UpdateExecutedInfo();
873
874 uint64_t id = task->taskId_ + MAX_TIMEOUT_TIME;
875 std::unordered_set<uint64_t> set{ task->taskId_, id };
876 worker->longTasksSet_ = std::move(set);
877 worker->TerminateTask(task->taskId_);
878 }
879
HandleFunctionException(napi_env env)880 void NativeEngineTest::HandleFunctionException(napi_env env)
881 {
882 ExceptionScope scope(env);
883 Worker* worker = reinterpret_cast<Worker*>(WorkerConstructor(env));
884 napi_env workerEnv = nullptr;
885 napi_create_runtime(env, &workerEnv);
886 worker->workerEnv_ = workerEnv;
887 Task* task = new Task();
888 task->taskId_ = reinterpret_cast<uint64_t>(task);
889 task->env_ = workerEnv;
890 TaskResultInfo* resultInfo = new TaskResultInfo(env, workerEnv, task->taskId_, nullptr);
891 TaskManager::GetInstance().NotifyCallbackExecute(env, resultInfo, task);
892 task->IncreaseRefCount();
893 uv_loop_t* loop = NapiHelper::GetLibUV(env);
894 ConcurrentHelper::UvHandleInit(loop, task->onResultSignal_, NativeEngineTest::foo, task);
895 task->worker_ = worker;
896 Worker::HandleFunctionException(env, task);
897 task->IncreaseRefCount();
898 Worker::HandleFunctionException(env, task);
899 }
900
WorkerConstructor(napi_env env)901 void* NativeEngineTest::WorkerConstructor(napi_env env)
902 {
903 uint32_t sleepTime = 50000; // 50000: is sleep 50ms
904 Worker* worker = Worker::WorkerConstructor(env);
905 usleep(sleepTime);
906 uv_loop_t* loop = worker->GetWorkerLoop();
907 ConcurrentHelper::UvHandleInit(loop, worker->performTaskSignal_, NativeEngineTest::foo, worker);
908 return worker;
909 }
910
GetWorkerTid(uv_timer_t * handle)911 pid_t NativeEngineTest::GetWorkerTid(uv_timer_t* handle)
912 {
913 Worker* worker = reinterpret_cast<Worker*>(handle->data);
914 return worker->tid_;
915 }
916 } // namespace Commonlibrary::Concurrent::TaskPoolModule