• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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