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 29namespace Commonlibrary::Concurrent::TaskPoolModule { 30 31static constexpr uint32_t MAX_TIMEOUT_TIME = 600000; 32static constexpr uint32_t FINSHED_TASK_ = 5; 33static constexpr uint32_t TASK_NUMS_ = 7; 34static constexpr uint64_t UINT64_ZERO_ = 0; 35static constexpr uint32_t UINT32_ZERO_ = 0; 36static constexpr uint32_t UINT32_ONE_ = 1; 37static constexpr size_t SIZE_TWO_ = 2; 38static constexpr size_t SIZE_THREE_ = 3; 39 40napi_ref CreateReference(napi_env env) 41{ 42 napi_value obj = NapiHelper::CreateObject(env); 43 return NapiHelper::CreateReference(env, obj, 1); 44} 45 46napi_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 65napi_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 73napi_value SendableUtils::Foo(napi_env env, napi_callback_info info) 74{ 75 return nullptr; 76} 77 78napi_value SendableUtils::Bar(napi_env env, napi_callback_info info) 79{ 80 return nullptr; 81} 82 83napi_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 93napi_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 103napi_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 113napi_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 123napi_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 133napi_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 143void NativeEngineTest::TaskGroupDestructor(napi_env env, void* data) 144{ 145 void* hint = nullptr; 146 TaskGroup::TaskGroupDestructor(env, data, hint); 147} 148 149void NativeEngineTest::SequenceRunnerDestructor(napi_env env, void* data) 150{ 151 void* hint = nullptr; 152 SequenceRunner::SequenceRunnerDestructor(env, data, hint); 153} 154 155napi_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 165napi_value NativeEngineTest::ExecuteGroup(napi_env env, napi_value taskGroup) 166{ 167 return TaskPool::ExecuteGroup(env, taskGroup, Priority::DEFAULT); 168} 169 170void NativeEngineTest::DelayTask(uv_timer_t* handle) 171{ 172 TaskPool::DelayTask(handle); 173} 174 175void NativeEngineTest::PeriodicTaskCallback(uv_timer_t* handle) 176{ 177 TaskPool::PeriodicTaskCallback(handle); 178} 179 180void 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 186void 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 195void 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 225void NativeEngineTest::foo(const uv_async_t* req) 226{ 227 return; 228} 229 230void 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 264void 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 305void 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 326void 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 361void 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 378void 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 399void 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 419void 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 437void 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 444void 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 451void 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 459void 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 473void 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 497void 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 535void 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 562void 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 597void 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->finishedTask = 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 647void NativeEngineTest::CancelGroupTask(napi_env env) 648{ 649 TaskGroupManager& groupManager = TaskGroupManager::GetInstance(); 650 TaskManager& taskManager = TaskManager::GetInstance(); 651 TaskGroup* group = new TaskGroup(); 652 Task* task = new Task(); 653 task->taskId_ = reinterpret_cast<uint64_t>(task); 654 taskManager.StoreTask(task->taskId_, task); 655 task->taskState_ = ExecuteState::RUNNING; 656 groupManager.CancelGroupTask(env, task->taskId_, group); 657 task->taskState_ = ExecuteState::WAITING; 658 groupManager.CancelGroupTask(env, task->taskId_, group); 659 task->taskState_ = ExecuteState::WAITING; 660 TaskInfo* taskInfo = new TaskInfo(); 661 task->currentTaskInfo_ = taskInfo; 662 groupManager.CancelGroupTask(env, task->taskId_, group); 663 664 Task* task1 = new Task(); 665 task1->taskId_ = reinterpret_cast<uint64_t>(task1); 666 SequenceRunner* seqRunner = new SequenceRunner(); 667 uint64_t seqRunnerId = reinterpret_cast<uint64_t>(seqRunner); 668 groupManager.StoreSequenceRunner(seqRunnerId, seqRunner); 669 groupManager.AddTaskToSeqRunner(seqRunnerId, task1); 670} 671 672void NativeEngineTest::TriggerSeqRunner(napi_env env) 673{ 674 TaskGroupManager& groupManager = TaskGroupManager::GetInstance(); 675 Task* task = new Task(); 676 task->taskId_ = reinterpret_cast<uint64_t>(task); 677 Task* task1 = new Task(); 678 task1->taskId_ = reinterpret_cast<uint64_t>(task1); 679 SequenceRunner* seqRunner = new SequenceRunner(); 680 uint64_t seqRunnerId = reinterpret_cast<uint64_t>(seqRunner); 681 seqRunner->priority_ = Priority::DEFAULT; 682 task->seqRunnerId_ = seqRunnerId; 683 groupManager.StoreSequenceRunner(seqRunnerId, seqRunner); 684 seqRunner->isGlobalRunner_ = true; 685 bool res = groupManager.TriggerSeqRunner(env, task); 686 ASSERT_FALSE(res); 687 seqRunner->globalSeqRunnerRef_.emplace(env, CreateReference(env)); 688 seqRunner->currentTaskId_ = task1->taskId_; 689 groupManager.TriggerSeqRunner(env, task); 690 seqRunner->isGlobalRunner_ = false; 691 seqRunner->seqRunnerRef_ = CreateReference(env); 692 seqRunner->currentTaskId_ = task->taskId_; 693 groupManager.TriggerSeqRunner(env, task); 694 seqRunner->seqRunnerRef_ = CreateReference(env); 695 task1->taskState_ = ExecuteState::CANCELED; 696 seqRunner->seqRunnerTasks_.push(task1); 697 TaskInfo* taskInfo = new TaskInfo(); 698 task1->currentTaskInfo_ = taskInfo; 699 seqRunner->currentTaskId_ = task->taskId_; 700 groupManager.TriggerSeqRunner(env, task); 701 seqRunner->seqRunnerRef_ = CreateReference(env); 702 TaskInfo* taskInfo1 = new TaskInfo(); 703 task1->currentTaskInfo_ = taskInfo1; 704 seqRunner->seqRunnerTasks_.push(task1); 705 seqRunner->seqRunnerTasks_.push(task); 706 task->taskState_ = ExecuteState::RUNNING; 707 seqRunner->currentTaskId_ = task->taskId_; 708 groupManager.TriggerSeqRunner(env, task); 709} 710 711void NativeEngineTest::UpdateGroupState(napi_env env) 712{ 713 TaskGroupManager& groupManager = TaskGroupManager::GetInstance(); 714 TaskGroup* group = new TaskGroup(); 715 uint64_t groupId = reinterpret_cast<uint64_t>(group); 716 Task* task = new Task(); 717 task->taskId_ = reinterpret_cast<uint64_t>(task); 718 groupManager.StoreTaskGroup(groupId, group); 719 groupManager.UpdateGroupState(task->taskId_); 720 group->groupState_ = ExecuteState::CANCELED; 721 groupManager.UpdateGroupState(groupId); 722 group->groupState_ = ExecuteState::WAITING; 723 groupManager.UpdateGroupState(groupId); 724 725 SequenceRunnerManager& runnerManager = SequenceRunnerManager::GetInstance(); 726 napi_value obj = NapiHelper::CreateObject(env); 727 SequenceRunner* seqRunner = runnerManager.CreateOrGetGlobalRunner(env, obj, SIZE_THREE_, "test", UINT32_ONE_); 728 seqRunner->priority_ = Priority::MEDIUM; 729 runnerManager.CreateOrGetGlobalRunner(env, obj, SIZE_TWO_, "test", UINT32_ZERO_); 730 runnerManager.CreateOrGetGlobalRunner(env, obj, SIZE_TWO_, "test", UINT32_ONE_); 731 runnerManager.DecreaseSeqCount(seqRunner); 732 runnerManager.RemoveGlobalSeqRunnerRef(env, seqRunner); 733 runnerManager.RemoveSequenceRunner("func"); 734 runnerManager.RemoveSequenceRunner("test"); 735} 736 737void NativeEngineTest::ReleaseWorkerHandles(napi_env env) 738{ 739 ExceptionScope scope(env); 740 Worker* worker = reinterpret_cast<Worker*>(WorkerConstructor(env)); 741 napi_env workerEnv = nullptr; 742 napi_create_runtime(env, &workerEnv); 743 worker->workerEnv_ = workerEnv; 744 NativeEngine* workerEngine = reinterpret_cast<NativeEngine*>(workerEnv); 745 uv_loop_t* loop = worker->GetWorkerLoop(); 746 ConcurrentHelper::UvHandleInit(loop, worker->performTaskSignal_, 747 NativeEngineTest::foo, worker); 748 ConcurrentHelper::UvHandleInit(loop, worker->debuggerOnPostTaskSignal_, 749 NativeEngineTest::foo, worker); 750 ConcurrentHelper::UvHandleInit(loop, worker->clearWorkerSignal_, 751 NativeEngineTest::foo, worker); 752 uv_async_t* req = new uv_async_t; 753 req->data = worker; 754 Worker::ReleaseWorkerHandles(req); 755} 756 757void NativeEngineTest::DebuggerOnPostTask(napi_env env) 758{ 759 ExceptionScope scope(env); 760 Worker* worker = reinterpret_cast<Worker*>(WorkerConstructor(env)); 761 uv_loop_t* loop = worker->GetWorkerLoop(); 762 ConcurrentHelper::UvHandleInit(loop, worker->debuggerOnPostTaskSignal_, 763 NativeEngineTest::foo, worker); 764 std::function<void()> myTask = []() { 765 return; 766 }; 767 worker->DebuggerOnPostTask(std::move(myTask)); 768 uv_async_t* req = new uv_async_t; 769 std::function<void()> myTask1 = []() { 770 return; 771 }; 772 worker->debuggerQueue_.push(myTask1); 773 req->data = worker; 774 worker->debuggerMutex_.unlock(); 775 Worker::HandleDebuggerTask(req); 776 worker->workerEnv_ = nullptr; 777 worker->ReleaseWorkerThreadContent(); 778 napi_env workerEnv = nullptr; 779 napi_create_runtime(env, &workerEnv); 780 worker->workerEnv_ = workerEnv; 781 worker->hostEnv_ = nullptr; 782 worker->state_ = WorkerState::BLOCKED; 783 worker->ReleaseWorkerThreadContent(); 784 napi_env workerEnv1 = nullptr; 785 napi_create_runtime(env, &workerEnv1); 786 worker->hostEnv_ = env; 787 worker->workerEnv_ = workerEnv1; 788 worker->state_ = WorkerState::IDLE; 789 worker->ReleaseWorkerThreadContent(); 790} 791 792void NativeEngineTest::PerformTask(napi_env env) 793{ 794 ExceptionScope scope(env); 795 TaskManager& taskManager = TaskManager::GetInstance(); 796 Worker* worker = reinterpret_cast<Worker*>(WorkerConstructor(env)); 797 napi_env workerEnv = nullptr; 798 napi_create_runtime(env, &workerEnv); 799 worker->workerEnv_ = workerEnv; 800 801 TaskGroup* group = new TaskGroup(); 802 uint64_t groupId = reinterpret_cast<uint64_t>(group); 803 group->groupState_ = ExecuteState::WAITING; 804 TaskGroupManager& groupManager = TaskGroupManager::GetInstance(); 805 groupManager.StoreTaskGroup(groupId, group); 806 807 Task* task = new Task(); 808 task->taskId_ = reinterpret_cast<uint64_t>(task); 809 taskManager.StoreTask(task->taskId_, task); 810 Priority priority = Priority::DEFAULT; 811 auto& mediumTaskQueue = taskManager.taskQueues_[priority]; 812 uint64_t id = mediumTaskQueue->DequeueTaskId(); 813 while (id != 0) { 814 id = mediumTaskQueue->DequeueTaskId(); 815 } 816 mediumTaskQueue->EnqueueTaskId(task->taskId_); 817 818 uv_async_t* req = new uv_async_t; 819 req->data = worker; 820 task->taskState_ = ExecuteState::WAITING; 821 task->taskType_ = TaskType::GROUP_COMMON_TASK; 822 task->groupId_ = groupId; 823 Worker::PerformTask(req); 824 usleep(100000); // 100000: is sleep 100ms 825} 826 827void NativeEngineTest::NotifyHandleTaskResult(napi_env env) 828{ 829 ExceptionScope scope(env); 830 Worker* worker = reinterpret_cast<Worker*>(WorkerConstructor(env)); 831 Task* task = new Task(); 832 task->taskId_ = reinterpret_cast<uint64_t>(task); 833 task->env_ = worker->workerEnv_; 834 uv_loop_t* loop = worker->GetWorkerLoop(); 835 ConcurrentHelper::UvHandleInit(loop, task->onResultSignal_, NativeEngineTest::foo, task); 836 Task* task1 = new Task(); 837 task1->taskId_ = reinterpret_cast<uint64_t>(task1); 838 worker->currentTaskId_.push_back(task1->taskId_); 839 task->worker_ = worker; 840 task->isMainThreadTask_ = true; 841 task->taskRefCount_.fetch_add(1); 842 TaskManager::GetInstance().StoreTask(task->taskId_, task); 843 Worker::NotifyHandleTaskResult(task); 844} 845 846void NativeEngineTest::TaskResultCallback(napi_env env) 847{ 848 ExceptionScope scope(env); 849 Worker* worker = reinterpret_cast<Worker*>(WorkerConstructor(env)); 850 Task* task = new Task(); 851 task->taskId_ = reinterpret_cast<uint64_t>(task); 852 task->env_ = worker->workerEnv_; 853 task->taskRefCount_.fetch_add(1); 854 task->worker_ = worker; 855 task->cpuTime_ = UINT64_ZERO_; 856 Worker::TaskResultCallback(worker->workerEnv_, nullptr, false, reinterpret_cast<void*>(task)); 857 task->taskRefCount_.fetch_add(1); 858 task->cpuTime_ = task->taskId_; 859 Worker::TaskResultCallback(worker->workerEnv_, nullptr, true, reinterpret_cast<void*>(task)); 860 861 worker->priority_ = Priority::LOW; 862 worker->ResetWorkerPriority(); 863 TaskManager& taskManager = TaskManager::GetInstance(); 864 taskManager.globalEnableFfrtFlag_ = true; 865 worker->priority_ = Priority::HIGH; 866 worker->ResetWorkerPriority(); 867 taskManager.globalEnableFfrtFlag_ = false; 868 worker->state_ = WorkerState::BLOCKED; 869 worker->UpdateExecutedInfo(); 870 worker->state_ = WorkerState::IDLE; 871 worker->UpdateExecutedInfo(); 872 873 uint64_t id = task->taskId_ + MAX_TIMEOUT_TIME; 874 std::unordered_set<uint64_t> set{ task->taskId_, id }; 875 worker->longTasksSet_ = std::move(set); 876 worker->TerminateTask(task->taskId_); 877} 878 879void NativeEngineTest::HandleFunctionException(napi_env env) 880{ 881 ExceptionScope scope(env); 882 Worker* worker = reinterpret_cast<Worker*>(WorkerConstructor(env)); 883 napi_env workerEnv = nullptr; 884 napi_create_runtime(env, &workerEnv); 885 worker->workerEnv_ = workerEnv; 886 Task* task = new Task(); 887 task->taskId_ = reinterpret_cast<uint64_t>(task); 888 task->env_ = workerEnv; 889 TaskResultInfo* resultInfo = new TaskResultInfo(env, workerEnv, task->taskId_, nullptr); 890 TaskManager::GetInstance().NotifyCallbackExecute(env, resultInfo, task); 891 task->IncreaseRefCount(); 892 uv_loop_t* loop = NapiHelper::GetLibUV(env); 893 ConcurrentHelper::UvHandleInit(loop, task->onResultSignal_, NativeEngineTest::foo, task); 894 task->worker_ = worker; 895 Worker::HandleFunctionException(env, task); 896 task->IncreaseRefCount(); 897 Worker::HandleFunctionException(env, task); 898} 899 900void* NativeEngineTest::WorkerConstructor(napi_env env) 901{ 902 uint32_t sleepTime = 50000; // 50000: is sleep 50ms 903 Worker* worker = Worker::WorkerConstructor(env); 904 usleep(sleepTime); 905 uv_loop_t* loop = worker->GetWorkerLoop(); 906 ConcurrentHelper::UvHandleInit(loop, worker->performTaskSignal_, NativeEngineTest::foo, worker); 907 return worker; 908} 909 910pid_t NativeEngineTest::GetWorkerTid(uv_timer_t* handle) 911{ 912 Worker* worker = reinterpret_cast<Worker*>(handle->data); 913 return worker->tid_; 914} 915} // namespace Commonlibrary::Concurrent::TaskPoolModule