1 /* 2 * Copyright (c) 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 #ifndef COMMON_COMPONENTS_HEAP_COLLECTOR_COLLECTOR_RESOURCES_H 17 #define COMMON_COMPONENTS_HEAP_COLLECTOR_COLLECTOR_RESOURCES_H 18 19 #include "common_components/heap/collector/finalizer_processor.h" 20 #include "common_components/heap/collector/task_queue.h" 21 #include "common_components/taskpool/taskpool.h" 22 23 namespace common { 24 class CollectorProxy; 25 // CollectorResources provides the resources that a functional collector need, 26 // such as gc thread/threadPool, gc task queue... 27 class CollectorResources { 28 public: 29 // the collector thread entry routine. 30 PUBLIC_API static void* GCMainThreadEntry(void* arg); 31 32 // a collectorResources without a collector entity is functionless CollectorResources(CollectorProxy & proxy)33 explicit CollectorResources(CollectorProxy& proxy) : collectorProxy_(proxy) {} 34 NO_INLINE_CC virtual ~CollectorResources() = default; 35 36 void Init(); 37 void Fini(); 38 void StopGCWork(); 39 void RequestGC(GCReason reason, bool async, GCType gcType); 40 void WaitForGCFinish(); 41 // gc main loop 42 void RunTaskLoop(); 43 uint32_t GetGCThreadCount(const bool isConcurrent) const; 44 GetThreadPool()45 Taskpool *GetThreadPool() const { return gcThreadPool_; } 46 IsHeapMarked()47 bool IsHeapMarked() const { return isHeapMarked_; } 48 SetHeapMarked(bool value)49 void SetHeapMarked(bool value) { isHeapMarked_ = value; } 50 IsGcStarted()51 bool IsGcStarted() const { return isGcStarted_.load(std::memory_order_relaxed); } 52 SetGcStarted(bool val)53 void SetGcStarted(bool val) { isGcStarted_.store(val, std::memory_order_relaxed); } 54 IsNativeGCInvoked()55 bool IsNativeGCInvoked() const { return isNativeGCInvoked_.load(std::memory_order_relaxed); } 56 SetIsNativeGCInvoked(bool val)57 void SetIsNativeGCInvoked(bool val) { isNativeGCInvoked_.store(val, std::memory_order_relaxed); } 58 IsGCActive()59 bool IsGCActive() const { return Heap::GetHeap().IsGCEnabled(); } 60 GetFinalizerProcessor()61 FinalizerProcessor& GetFinalizerProcessor() { return finalizerProcessor_; } 62 63 void BroadcastGCFinished(); GetGCStats()64 GCStats& GetGCStats() { return gcStats_; } GetGCStats()65 const GCStats& GetGCStats() const { return gcStats_; } 66 void RequestHeapDump(GCTask::GCTaskType gcTask); 67 68 void StartRuntimeThreads(); 69 void StopRuntimeThreads(); 70 71 void MarkGCStart(); 72 void MarkGCFinish(uint64_t gcIndex = 0); 73 74 private: 75 // Notify that GC has finished. 76 void NotifyGCFinished(uint64_t gcIndex); 77 78 void StartGCThreads(); 79 void TerminateGCTask(); 80 void StopGCThreads(); 81 // Notify the GC thread to start GC, and wait. 82 // Called by mutator. 83 // reason: The reason for this GC. 84 void RequestAsyncGC(GCReason reason, GCType gcType); 85 void RequestGCAndWait(GCReason reason, GCType gcType); 86 void PostIgnoredGcRequest(GCReason reason); 87 88 // the thread pool for parallel tracing. 89 Taskpool *gcThreadPool_ = nullptr; 90 uint32_t gcThreadCount_ = 1; 91 GCTaskQueue<GCRunner>* taskQueue_ = nullptr; 92 93 // the collector thread handle. 94 pthread_t gcMainThread_ = 0; 95 std::atomic<pid_t> gcTid_{ 0 }; 96 std::atomic<bool> gcThreadRunning_ = { false }; 97 // finishedGcIndex records the currently finished gcIndex 98 // may be read by mutator but only be written by gc thread sequentially 99 std::atomic<uint64_t> finishedGcIndex_ = { 0 }; 100 // protect condition_variable gcFinishedCondVar's status. 101 std::mutex gcFinishedCondMutex_; 102 // notified when GC finished, requires gcFinishedCondMutex 103 std::condition_variable gcFinishedCondVar_; 104 105 // Indicate whether GC is already started. 106 // NOTE: When GC finishes, it clears isGcStarted, must be over-written only by gc thread. 107 std::atomic<bool> isGcStarted_ = { false }; 108 std::atomic<bool> isNativeGCInvoked_ = {false}; 109 110 // only gc thread can access it, so we don't use atomic type 111 bool isHeapMarked_ = false; 112 // Represent the number of returned raw pointer 113 std::atomic<int> criticalNum_{ 0 }; 114 int gcWorking_ = 0; 115 #if defined(_WIN64) || defined(__APPLE__) 116 std::condition_variable gcWorkingCV; 117 std::mutex gcWorkingMtx; WaitUntilGCDone()118 __attribute__((always_inline)) inline void WaitUntilGCDone() 119 { 120 std::unique_lock<std::mutex> gcWorkingLck(gcWorkingMtx); 121 gcWorkingCV.wait(gcWorkingLck); 122 } 123 WakeWhenGCDone()124 __attribute__((always_inline)) inline void WakeWhenGCDone() 125 { 126 std::unique_lock<std::mutex> gcWorkingLck(gcWorkingMtx); 127 gcWorkingCV.notify_all(); 128 } 129 #endif 130 CollectorProxy& collectorProxy_; 131 FinalizerProcessor finalizerProcessor_; 132 GCStats gcStats_; 133 bool hasRelease = false; 134 }; 135 } // namespace common 136 137 #endif // COMMON_COMPONENTS_HEAP_COLLECTOR_COLLECTOR_RESOURCES_H 138