• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-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 <utility>
17 
18 #include "libpandabase/os/cpu_affinity.h"
19 #include "runtime/mem/gc/gc.h"
20 #include "runtime/mem/gc/workers/gc_workers_thread_pool.h"
21 
22 namespace ark::mem {
23 
Init()24 bool GCWorkersProcessor::Init()
25 {
26     return gcThreadsPools_->GetGC()->InitWorker(&workerData_);
27 }
28 
Destroy()29 bool GCWorkersProcessor::Destroy()
30 {
31     gcThreadsPools_->GetGC()->DestroyWorker(workerData_);
32     return true;
33 }
34 
Process(GCWorkersTask && task)35 bool GCWorkersProcessor::Process(GCWorkersTask &&task)
36 {
37     gcThreadsPools_->RunGCWorkersTask(&task, workerData_);
38     return true;
39 }
40 
GCWorkersThreadPool(GC * gc,size_t threadsCount)41 GCWorkersThreadPool::GCWorkersThreadPool(GC *gc, size_t threadsCount)
42     : GCWorkersTaskPool(gc), internalAllocator_(gc->GetInternalAllocator()), threadsCount_(threadsCount)
43 {
44     ASSERT(gc->GetPandaVm() != nullptr);
45     queue_ = internalAllocator_->New<GCWorkersQueueSimple>(internalAllocator_, QUEUE_SIZE_MAX_SIZE);
46     workerIface_ = internalAllocator_->New<GCWorkersCreationInterface>(gc->GetPandaVm());
47     threadPool_ = internalAllocator_->New<ThreadPool<GCWorkersTask, GCWorkersProcessor, GCWorkersThreadPool *>>(
48         internalAllocator_, queue_, this, threadsCount, "GC_WORKER",
49         static_cast<WorkerCreationInterface *>(workerIface_));
50 }
51 
TryAddTask(GCWorkersTask && task)52 bool GCWorkersThreadPool::TryAddTask(GCWorkersTask &&task)
53 {
54     return threadPool_->TryPutTask(std::forward<GCWorkersTask &&>(task));
55 }
56 
SetAffinity(GCWorkersProcessor * proc,size_t gcThreadsCount)57 static void SetAffinity(GCWorkersProcessor *proc, size_t gcThreadsCount)
58 {
59     // For first GC, GC-workers can be not started
60     if (UNLIKELY(!proc->IsStarted())) {
61         return;
62     }
63     const auto &bestAndMiddle = os::CpuAffinityManager::GetBestAndMiddleCpuSet();
64     if (gcThreadsCount < bestAndMiddle.Count()) {
65         os::CpuAffinityManager::SetAffinityForThread(proc->GetTid(), bestAndMiddle);
66     }
67 }
68 
UnsetAffinity(GCWorkersProcessor * proc,size_t data)69 static void UnsetAffinity(GCWorkersProcessor *proc, [[maybe_unused]] size_t data)
70 {
71     os::CpuAffinityManager::SetAffinityForThread(proc->GetTid(), os::CpuPower::WEAK);
72 }
73 
SetAffinityForGCWorkers()74 void GCWorkersThreadPool::SetAffinityForGCWorkers()
75 {
76     // Total GC threads count = GC Thread + GC workers
77     threadPool_->EnumerateProcs(SetAffinity, threadsCount_ + 1U);
78 }
79 
UnsetAffinityForGCWorkers()80 void GCWorkersThreadPool::UnsetAffinityForGCWorkers()
81 {
82     threadPool_->EnumerateProcs(UnsetAffinity, 0U);
83 }
84 
~GCWorkersThreadPool()85 GCWorkersThreadPool::~GCWorkersThreadPool()
86 {
87     internalAllocator_->Delete(threadPool_);
88     internalAllocator_->Delete(workerIface_);
89     queue_->Finalize();
90     internalAllocator_->Delete(queue_);
91 }
92 
RunInCurrentThread()93 void GCWorkersThreadPool::RunInCurrentThread()
94 {
95     threadPool_->Help();
96 }
97 
98 }  // namespace ark::mem
99