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 #include "ecmascript/taskpool/runner.h"
17
18 #include "ecmascript/platform/mutex.h"
19 #include "libpandabase/os/thread.h"
20 #ifdef ENABLE_QOS
21 #include "qos.h"
22 #endif
23
24 namespace panda::ecmascript {
Runner(uint32_t threadNum)25 Runner::Runner(uint32_t threadNum) : totalThreadNum_(threadNum)
26 {
27 for (uint32_t i = 0; i < threadNum; i++) {
28 // main thread is 0;
29 std::unique_ptr<std::thread> thread = std::make_unique<std::thread>(&Runner::Run, this, i + 1);
30 threadPool_.emplace_back(std::move(thread));
31 }
32
33 for (uint32_t i = 0; i < runningTask_.size(); i++) {
34 runningTask_[i] = nullptr;
35 }
36 }
37
TerminateTask(int32_t id,TaskType type)38 void Runner::TerminateTask(int32_t id, TaskType type)
39 {
40 taskQueue_.TerminateTask(id, type);
41 LockHolder holder(mtx_);
42 for (uint32_t i = 0; i < runningTask_.size(); i++) {
43 if (runningTask_[i] != nullptr) {
44 if (id != ALL_TASK_ID && id != runningTask_[i]->GetId()) {
45 continue;
46 }
47 if (type != TaskType::ALL && type != runningTask_[i]->GetTaskType()) {
48 continue;
49 }
50 runningTask_[i]->Terminated();
51 }
52 }
53 }
54
TerminateThread()55 void Runner::TerminateThread()
56 {
57 TerminateTask(ALL_TASK_ID, TaskType::ALL);
58 taskQueue_.Terminate();
59
60 LockHolder holder(mtxPool_);
61 uint32_t threadNum = threadPool_.size();
62 for (uint32_t i = 0; i < threadNum; i++) {
63 threadPool_.at(i)->join();
64 }
65 threadPool_.clear();
66 }
67
SetQosPriority(bool isForeground)68 void Runner::SetQosPriority([[maybe_unused]] bool isForeground)
69 {
70 #ifdef ENABLE_QOS
71 if (isForeground) {
72 for (uint32_t threadId : gcThreadId_) {
73 OHOS::QOS::SetQosForOtherThread(OHOS::QOS::QosLevel::QOS_USER_INITIATED, threadId);
74 }
75 } else {
76 for (uint32_t threadId : gcThreadId_) {
77 OHOS::QOS::ResetQosForOtherThread(threadId);
78 }
79 }
80 #endif
81 }
82
RecordThreadId()83 void Runner::RecordThreadId()
84 {
85 LockHolder holder(mtx_);
86 gcThreadId_.emplace_back(os::thread::GetCurrentThreadId());
87 }
88
SetRunTask(uint32_t threadId,Task * task)89 void Runner::SetRunTask(uint32_t threadId, Task *task)
90 {
91 LockHolder holder(mtx_);
92 runningTask_[threadId] = task;
93 }
94
Run(uint32_t threadId)95 void Runner::Run(uint32_t threadId)
96 {
97 os::thread::native_handle_type thread = os::thread::GetNativeHandle();
98 os::thread::SetThreadName(thread, "OS_GC_Thread");
99 RecordThreadId();
100 while (std::unique_ptr<Task> task = taskQueue_.PopTask()) {
101 SetRunTask(threadId, task.get());
102 task->Run(threadId);
103 SetRunTask(threadId, nullptr);
104 }
105 }
106 } // namespace panda::ecmascript
107