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 #ifndef PANDA_RUNTIME_MEM_GC_G1_UPDATE_REMSET_THREAD_H 17 #define PANDA_RUNTIME_MEM_GC_G1_UPDATE_REMSET_THREAD_H 18 19 #include "runtime/mem/gc/g1/update_remset_worker.h" 20 21 #include "libpandabase/macros.h" 22 #include "libpandabase/os/mutex.h" 23 #include "runtime/include/mem/panda_containers.h" 24 25 namespace ark::mem { 26 27 constexpr bool REMSET_THREAD_USE_STATS = false; 28 29 class RemsetThreadStats { 30 public: 31 void IncAddedCardToQueue(size_t value = 1) 32 { 33 if (REMSET_THREAD_USE_STATS) { 34 addedCardsToQueue_ += value; 35 } 36 } 37 IncProcessedConcurrentCards(const PandaUnorderedSet<CardTable::CardPtr> & cards)38 void IncProcessedConcurrentCards(const PandaUnorderedSet<CardTable::CardPtr> &cards) 39 { 40 if (REMSET_THREAD_USE_STATS) { 41 processedConcurrentCards_ += cards.size(); 42 for (const auto &card : cards) { 43 uniqueCards_.insert(card); 44 } 45 } 46 } 47 IncProcessedAtSTWCards(const PandaUnorderedSet<CardTable::CardPtr> & cards)48 void IncProcessedAtSTWCards(const PandaUnorderedSet<CardTable::CardPtr> &cards) 49 { 50 if (REMSET_THREAD_USE_STATS) { 51 processedAtStwCards_ += cards.size(); 52 for (const auto &card : cards) { 53 uniqueCards_.insert(card); 54 } 55 } 56 } 57 Reset()58 void Reset() 59 { 60 addedCardsToQueue_ = processedConcurrentCards_ = processedAtStwCards_ = 0; 61 uniqueCards_.clear(); 62 } 63 PrintStats()64 void PrintStats() const 65 { 66 if (REMSET_THREAD_USE_STATS) { 67 LOG(DEBUG, GC) << "remset thread stats: " 68 << "added_cards_to_queue: " << addedCardsToQueue_ 69 << " processed_concurrent_cards: " << processedConcurrentCards_ 70 << " processed_at_stw_cards: " << processedAtStwCards_ 71 << " uniq_cards_processed: " << uniqueCards_.size(); 72 } 73 } 74 75 private: 76 std::atomic<size_t> addedCardsToQueue_ {0}; 77 std::atomic<size_t> processedConcurrentCards_ {0}; 78 std::atomic<size_t> processedAtStwCards_ {0}; 79 PandaUnorderedSet<CardTable::CardPtr> uniqueCards_; 80 }; 81 82 template <class LanguageConfig> 83 class UpdateRemsetThread final : public UpdateRemsetWorker<LanguageConfig> { 84 public: 85 explicit UpdateRemsetThread(G1GC<LanguageConfig> *gc, GCG1BarrierSet::ThreadLocalCardQueues *queue, 86 os::memory::Mutex *queueLock, size_t regionSize, bool updateConcurrent, 87 size_t minConcurrentCardsToProcess, size_t hotCardsProcessingFrequency); 88 ~UpdateRemsetThread() final; 89 NO_COPY_SEMANTIC(UpdateRemsetThread); 90 NO_MOVE_SEMANTIC(UpdateRemsetThread); 91 92 private: 93 void CreateWorkerImpl() final; 94 void DestroyWorkerImpl() final; 95 void ContinueProcessCards() REQUIRES(this->updateRemsetLock_) final; 96 97 void ThreadLoop(); 98 Sleep()99 void Sleep() REQUIRES(this->updateRemsetLock_) 100 { 101 static constexpr uint64_t SLEEP_MS = 1; 102 threadCondVar_.TimedWait(&this->updateRemsetLock_, SLEEP_MS); 103 } 104 105 /* Thread specific variables */ 106 std::thread *updateThread_ {nullptr}; 107 os::memory::ConditionVariable threadCondVar_ GUARDED_BY(this->updateRemsetLock_); 108 RemsetThreadStats stats_; 109 }; 110 111 } // namespace ark::mem 112 #endif // PANDA_RUNTIME_MEM_GC_G1_UPDATE_REMSET_THREAD_H 113