• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2023-2025 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     hasTaskInTaskmanager_ = true;
76     this->GetGC()->GetWorkersTaskQueue()->AddForegroundTask(taskRunner_);
77 }
78 
79 template <class LanguageConfig>
ContinueProcessCards()80 void UpdateRemsetTaskQueue<LanguageConfig>::ContinueProcessCards()
81 {
82     if (taskRunnerWaiterId_ != taskmanager::INVALID_WAITER_ID) {
83         this->GetGC()->GetWorkersTaskQueue()->SignalWaitList(taskRunnerWaiterId_);
84     } else {
85         StartProcessCards();
86     }
87 }
88 
89 template <class LanguageConfig>
CreateWorkerImpl()90 void UpdateRemsetTaskQueue<LanguageConfig>::CreateWorkerImpl()
91 {
92     os::memory::LockHolder lh(this->updateRemsetLock_);
93     ASSERT(!hasTaskInTaskmanager_);
94     StartProcessCards();
95 }
96 
97 template <class LanguageConfig>
DestroyWorkerImpl()98 void UpdateRemsetTaskQueue<LanguageConfig>::DestroyWorkerImpl()
99 {
100     this->GetGC()->GetWorkersTaskQueue()->WaitForegroundTasks();
101     [[maybe_unused]] os::memory::LockHolder lh(this->updateRemsetLock_);
102     ASSERT(!hasTaskInTaskmanager_);
103 }
104 
105 template <class LanguageConfig>
AddToWaitList()106 void UpdateRemsetTaskQueue<LanguageConfig>::AddToWaitList()
107 {
108     ASSERT(taskRunner_);
109     taskRunnerWaiterId_ = this->GetGC()->GetWorkersTaskQueue()->AddForegroundTaskInWaitList(taskRunner_);
110 }
111 
112 template <class LanguageConfig>
AddToWaitListWithTimeout()113 void UpdateRemsetTaskQueue<LanguageConfig>::AddToWaitListWithTimeout()
114 {
115     ASSERT(taskRunner_);
116     static constexpr uint64_t TIMEOUT_MS = 1U;
117     taskRunnerWaiterId_ = this->GetGC()->GetWorkersTaskQueue()->AddForegroundTaskInWaitList(taskRunner_, TIMEOUT_MS);
118 }
119 
120 TEMPLATE_CLASS_LANGUAGE_CONFIG(UpdateRemsetTaskQueue);
121 }  // namespace ark::mem
122