1 /* 2 * Copyright (c) 2021 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 ECMASCRIPT_TASKPOOL_RUNNER_H 17 #define ECMASCRIPT_TASKPOOL_RUNNER_H 18 19 #include <array> 20 #include <memory> 21 #include <thread> 22 #include <vector> 23 #include <functional> 24 25 #include "ecmascript/common.h" 26 #include "ecmascript/taskpool/task_queue.h" 27 #include "ecmascript/platform/mutex.h" 28 #include "libpandabase/os/thread.h" 29 30 namespace panda::ecmascript { 31 static constexpr uint32_t MIN_TASKPOOL_THREAD_NUM = 3; 32 static constexpr uint32_t MAX_TASKPOOL_THREAD_NUM = 5; 33 static constexpr uint32_t DEFAULT_TASKPOOL_THREAD_NUM = 0; 34 35 enum class PriorityMode { 36 STW, 37 FOREGROUND, 38 BACKGROUND 39 }; 40 41 class Runner { 42 public: 43 explicit Runner(uint32_t threadNum, 44 const std::function<void(os::thread::native_handle_type)> prologueHook, 45 const std::function<void(os::thread::native_handle_type)> epilogueHook); 46 ~Runner() = default; 47 48 NO_COPY_SEMANTIC(Runner); 49 NO_MOVE_SEMANTIC(Runner); 50 PostTask(std::unique_ptr<Task> task)51 void PostTask(std::unique_ptr<Task> task) 52 { 53 taskQueue_.PostTask(std::move(task)); 54 } 55 PostDelayedTask(std::unique_ptr<Task> task,uint64_t delayMilliseconds)56 void PostDelayedTask(std::unique_ptr<Task> task, uint64_t delayMilliseconds) 57 { 58 taskQueue_.PostDelayedTask(std::move(task), delayMilliseconds); 59 } 60 61 void PUBLIC_API TerminateThread(); 62 void TerminateTask(int32_t id, TaskType type); 63 void SetQosPriority(PriorityMode mode); 64 void RecordThreadId(); 65 GetTotalThreadNum()66 uint32_t GetTotalThreadNum() const 67 { 68 return totalThreadNum_; 69 } 70 IsInThreadPool(std::thread::id id)71 bool IsInThreadPool(std::thread::id id) 72 { 73 LockHolder holder(mtxPool_); 74 for (auto &thread : threadPool_) { 75 if (thread->get_id() == id) { 76 return true; 77 } 78 } 79 return false; 80 } 81 PrologueHook(os::thread::native_handle_type thread)82 void PrologueHook(os::thread::native_handle_type thread) 83 { 84 if (prologueHook_ != nullptr) { 85 prologueHook_(thread); 86 } 87 } EpilogueHook(os::thread::native_handle_type thread)88 void EpilogueHook(os::thread::native_handle_type thread) 89 { 90 if (epilogueHook_ != nullptr) { 91 epilogueHook_(thread); 92 } 93 } 94 void ForEachTask(const std::function<void(Task*)> &f); 95 96 private: 97 void Run(uint32_t threadId); 98 void SetRunTask(uint32_t threadId, Task *task); 99 100 std::vector<std::unique_ptr<std::thread>> threadPool_ {}; 101 TaskQueue taskQueue_ {}; 102 std::array<Task*, MAX_TASKPOOL_THREAD_NUM + 1> runningTask_; 103 uint32_t totalThreadNum_ {0}; 104 std::vector<uint32_t> gcThreadId_ {}; 105 Mutex mtx_; 106 Mutex mtxPool_; 107 108 std::function<void(os::thread::native_handle_type)> prologueHook_; 109 std::function<void(os::thread::native_handle_type)> epilogueHook_; 110 }; 111 } // namespace panda::ecmascript 112 #endif // ECMASCRIPT_TASKPOOL_RUNNER_H 113