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 #ifndef JS_CONCURRENT_MODULE_TASKPOOL_TASK_H 17 #define JS_CONCURRENT_MODULE_TASKPOOL_TASK_H 18 19 #include <list> 20 #include <mutex> 21 #include <shared_mutex> 22 #include <string> 23 #include <uv.h> 24 25 #include "helper/concurrent_helper.h" 26 #include "napi/native_api.h" 27 #include "utils.h" 28 #include "utils/log.h" 29 30 namespace Commonlibrary::Concurrent::TaskPoolModule { 31 using namespace Commonlibrary::Platform; 32 33 enum ExecuteState { NOT_FOUND, WAITING, RUNNING, CANCELED }; 34 enum TaskType { TASK, FUNCTION_TASK, SEQRUNNER_TASK, COMMON_TASK, GROUP_COMMON_TASK, GROUP_FUNCTION_TASK }; 35 36 struct GroupInfo; 37 struct TaskInfo { 38 napi_deferred deferred = nullptr; 39 Priority priority {Priority::DEFAULT}; 40 napi_value serializationFunction = nullptr; 41 napi_value serializationArguments = nullptr; 42 }; 43 44 class Task { 45 public: 46 Task(napi_env env, TaskType taskType, std::string name); 47 Task() = default; 48 ~Task() = default; 49 50 static napi_value TaskConstructor(napi_env env, napi_callback_info cbinfo); 51 static napi_value SetTransferList(napi_env env, napi_callback_info cbinfo); 52 static napi_value SetCloneList(napi_env env, napi_callback_info cbinfo); 53 static napi_value IsCanceled(napi_env env, napi_callback_info cbinfo); 54 static napi_value OnReceiveData(napi_env env, napi_callback_info cbinfo); 55 static napi_value SendData(napi_env env, napi_callback_info cbinfo); 56 static napi_value AddDependency(napi_env env, napi_callback_info cbinfo); 57 static napi_value RemoveDependency(napi_env env, napi_callback_info cbinfo); 58 static napi_value GetTotalDuration(napi_env env, napi_callback_info info); 59 static napi_value GetCPUDuration(napi_env env, napi_callback_info info); 60 static napi_value GetIODuration(napi_env env, napi_callback_info info); 61 static napi_value GetTaskDuration(napi_env env, napi_callback_info& info, std::string durationType); 62 63 static Task* GenerateTask(napi_env env, napi_value task, napi_value func, 64 napi_value name, napi_value* args, size_t argc); 65 static Task* GenerateFunctionTask(napi_env env, napi_value func, napi_value* args, size_t argc, TaskType type); 66 static TaskInfo* GenerateTaskInfo(napi_env env, napi_value func, napi_value args, 67 napi_value transferList, napi_value cloneList, Priority priority, 68 bool defaultTransfer = true, bool defaultCloneSendable = false); 69 static void TaskDestructor(napi_env env, void* data, void* hint); 70 71 static void IncreaseTaskRef(const uv_async_t* req); 72 73 void StoreTaskId(uint64_t taskId); 74 napi_value GetTaskInfoPromise(napi_env env, napi_value task, TaskType taskType = TaskType::COMMON_TASK, 75 Priority priority = Priority::DEFAULT); 76 TaskInfo* GetTaskInfo(napi_env env, napi_value task, TaskType taskType, Priority priority); 77 bool IsRepeatableTask(); 78 bool IsGroupTask(); 79 bool IsGroupCommonTask(); 80 bool IsGroupFunctionTask(); 81 bool IsCommonTask(); 82 bool IsSeqRunnerTask(); 83 bool IsFunctionTask(); 84 bool IsInitialized(); 85 void IncreaseRefCount(); 86 void DecreaseRefCount(); 87 bool IsReadyToHandle(); 88 void NotifyPendingTask(); 89 void CancelPendingTask(napi_env env, ExecuteState state); 90 bool UpdateTask(uint64_t startTime, void* worker); 91 napi_value DeserializeValue(napi_env env, bool isFunc, bool isArgs); 92 void StoreTaskDuration(); 93 bool CanForSequenceRunner(napi_env env); 94 bool CanForTaskGroup(napi_env env); 95 bool CanExecute(napi_env env); 96 bool CanExecuteDelayed(napi_env env); 97 98 private: 99 Task(const Task &) = delete; 100 Task& operator=(const Task &) = delete; 101 Task(Task &&) = delete; 102 Task& operator=(Task &&) = delete; 103 104 public: 105 napi_env env_ = nullptr; 106 TaskType taskType_ {TaskType::TASK}; 107 std::string name_ {}; 108 uint64_t taskId_ {}; 109 std::atomic<ExecuteState> taskState_ {ExecuteState::NOT_FOUND}; 110 uint64_t groupId_ {}; // 0 for task outside taskgroup 111 uint64_t seqRunnerId_ {}; // 0 for task without seqRunner 112 TaskInfo* currentTaskInfo_ {}; 113 std::list<TaskInfo*> pendingTaskInfos_ {}; // for a common task executes multiple times 114 napi_value result_ = nullptr; 115 uv_async_t* onResultSignal_ = nullptr; 116 uv_async_t* increaseRefSignal_ = nullptr; 117 std::atomic<bool> success_ {true}; 118 uint64_t startTime_ {}; 119 uint64_t cpuTime_ {}; 120 uint64_t ioTime_ {}; 121 void* worker_ {nullptr}; 122 napi_ref taskRef_ {}; 123 std::atomic<uint32_t> taskRefCount_ {}; 124 std::shared_mutex taskMutex_ {}; 125 }; 126 127 struct CallbackInfo { CallbackInfoCallbackInfo128 CallbackInfo(napi_env env, uint32_t count, napi_ref ref) 129 : hostEnv(env), refCount(count), callbackRef(ref), onCallbackSignal(nullptr) {} ~CallbackInfoCallbackInfo130 ~CallbackInfo() 131 { 132 napi_delete_reference(hostEnv, callbackRef); 133 if (onCallbackSignal != nullptr) { 134 Common::Helper::ConcurrentHelper::UvHandleClose(onCallbackSignal); 135 } 136 } 137 138 napi_env hostEnv; 139 uint32_t refCount; 140 napi_ref callbackRef; 141 uv_async_t* onCallbackSignal; 142 }; 143 144 struct TaskResultInfo { TaskResultInfoTaskResultInfo145 TaskResultInfo(napi_env env, uint64_t id, napi_value args) : hostEnv(env), 146 taskId(id), serializationArgs(args) {} 147 ~TaskResultInfo() = default; 148 149 napi_env hostEnv; 150 uint64_t taskId; 151 napi_value serializationArgs; 152 }; 153 } // namespace Commonlibrary::Concurrent::TaskPoolModule 154 #endif // JS_CONCURRENT_MODULE_TASKPOOL_TASK_H