• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2023-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 "runtime/mem/gc/g1/update_remset_task_queue.h"
17 
18 #include "libpandabase/taskmanager/task_scheduler.h"
19 #include "runtime/include/language_config.h"
20 #include "runtime/mem/gc/g1/g1-gc.h"
21 
22 namespace ark::mem {
23 
24 template <class LanguageConfig>
UpdateRemsetTaskQueue(G1GC<LanguageConfig> * gc,GCG1BarrierSet::ThreadLocalCardQueues * queue,os::memory::Mutex * queueLock,size_t regionSize,bool updateConcurrent,size_t minConcurrentCardsToProcess,size_t hotCardsProcessingFrequency)25 UpdateRemsetTaskQueue<LanguageConfig>::UpdateRemsetTaskQueue(G1GC<LanguageConfig> *gc,
26                                                              GCG1BarrierSet::ThreadLocalCardQueues *queue,
27                                                              os::memory::Mutex *queueLock, size_t regionSize,
28                                                              bool updateConcurrent, size_t minConcurrentCardsToProcess,
29                                                              size_t hotCardsProcessingFrequency)
30     : UpdateRemsetWorker<LanguageConfig>(gc, queue, queueLock, regionSize, updateConcurrent,
31                                          minConcurrentCardsToProcess, hotCardsProcessingFrequency)
32 {
33     taskRunner_ = [this]() {
34         os::memory::LockHolder lh(this->updateRemsetLock_);
35         taskRunnerWaiterId_ = taskmanager::INVALID_WAITER_ID;
36         ASSERT(this->hasTaskInTaskmanager_);
37 
38         auto iterationFlag = this->GetFlag();
39         if (iterationFlag == UpdateRemsetWorker<LanguageConfig>::UpdateRemsetWorkerFlags::IS_STOP_WORKER) {
40             this->hasTaskInTaskmanager_ = false;
41             return;
42         }
43 
44         if (iterationFlag == UpdateRemsetWorker<LanguageConfig>::UpdateRemsetWorkerFlags::IS_PAUSED_BY_GC_THREAD ||
45             iterationFlag == UpdateRemsetWorker<LanguageConfig>::UpdateRemsetWorkerFlags::IS_INVALIDATE_REGIONS) {
46             this->AddToWaitList();
47             return;
48         }
49 
50         ASSERT(!this->pausedByGcThread_);
51         auto processedCards = this->ProcessAllCards();
52         if (processedCards < this->GetMinConcurrentCardsToProcess()) {
53             // need to add to wait list with timeout
54             this->AddToWaitListWithTimeout();
55             return;
56         }
57 
58         // After cards processing add new cards processing task to task manager
59         this->hasTaskInTaskmanager_ = false;
60         this->StartProcessCards();
61     };
62 }
63 
64 template <class LanguageConfig>
65 UpdateRemsetTaskQueue<LanguageConfig>::~UpdateRemsetTaskQueue() = default;
66 
67 template <class LanguageConfig>
StartProcessCards()68 void UpdateRemsetTaskQueue<LanguageConfig>::StartProcessCards()
69 {
70     // If we already have process cards task in task manager then no need to add a new task
71     if (hasTaskInTaskmanager_) {
72         return;
73     }
74     ASSERT(taskRunner_);
75     auto processCardsTask = taskmanager::Task::Create(UPDATE_REMSET_TASK_PROPERTIES, taskRunner_);
76     hasTaskInTaskmanager_ = true;
77     this->GetGC()->GetWorkersTaskQueue()->AddTask(std::move(processCardsTask));
78 }
79 
80 template <class LanguageConfig>
ContinueProcessCards()81 void UpdateRemsetTaskQueue<LanguageConfig>::ContinueProcessCards()
82 {
83     if (taskRunnerWaiterId_ != taskmanager::INVALID_WAITER_ID) {
84         taskmanager::TaskScheduler::GetTaskScheduler()->SignalWaitList(taskRunnerWaiterId_);
85     } else {
86         StartProcessCards();
87     }
88 }
89 
90 template <class LanguageConfig>
CreateWorkerImpl()91 void UpdateRemsetTaskQueue<LanguageConfig>::CreateWorkerImpl()
92 {
93     os::memory::LockHolder lh(this->updateRemsetLock_);
94     ASSERT(!hasTaskInTaskmanager_);
95     StartProcessCards();
96 }
97 
98 template <class LanguageConfig>
DestroyWorkerImpl()99 void UpdateRemsetTaskQueue<LanguageConfig>::DestroyWorkerImpl()
100 {
101     taskmanager::TaskScheduler::GetTaskScheduler()->WaitForFinishAllTasksWithProperties(UPDATE_REMSET_TASK_PROPERTIES);
102     [[maybe_unused]] os::memory::LockHolder lh(this->updateRemsetLock_);
103     ASSERT(!hasTaskInTaskmanager_);
104 }
105 
106 template <class LanguageConfig>
AddToWaitList()107 void UpdateRemsetTaskQueue<LanguageConfig>::AddToWaitList()
108 {
109     ASSERT(taskRunner_);
110     auto processCardsTask = taskmanager::Task::Create(UPDATE_REMSET_TASK_PROPERTIES, taskRunner_);
111     taskRunnerWaiterId_ =
112         taskmanager::TaskScheduler::GetTaskScheduler()->AddTaskToWaitList(std::move(processCardsTask));
113 }
114 
115 template <class LanguageConfig>
AddToWaitListWithTimeout()116 void UpdateRemsetTaskQueue<LanguageConfig>::AddToWaitListWithTimeout()
117 {
118     ASSERT(taskRunner_);
119     auto processCardsTask = taskmanager::Task::Create(UPDATE_REMSET_TASK_PROPERTIES, taskRunner_);
120     static constexpr uint64_t TIMEOUT_MS = 1U;
121     taskRunnerWaiterId_ = taskmanager::TaskScheduler::GetTaskScheduler()->AddTaskToWaitListWithTimeout(
122         std::move(processCardsTask), TIMEOUT_MS);
123 }
124 
125 TEMPLATE_CLASS_LANGUAGE_CONFIG(UpdateRemsetTaskQueue);
126 }  // namespace ark::mem
127