• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_FINALIZER_PROCESSOR_H
17 #define COMMON_COMPONENTS_HEAP_COLLECTOR_FINALIZER_PROCESSOR_H
18 
19 #include <climits>
20 #include <condition_variable>
21 #include <list>
22 #include <mutex>
23 
24 #include "common_components/common/page_allocator.h"
25 #include "common_components/common/type_def.h"
26 #include "common_components/heap/collector/collector.h"
27 #include "common_components/log/log.h"
28 
29 namespace common {
30 template<typename T>
31 using ManagedList = std::list<T, StdContainerAllocator<T, FINALIZER_PROCESSOR>>;
32 
33 class FinalizerProcessor {
34 public:
35     FinalizerProcessor();
36     ~FinalizerProcessor() = default;
37 
38     // mainly for resurrection.
VisitFinalizers(const RootVisitor & visitor)39     uint32_t VisitFinalizers(const RootVisitor& visitor)
40     {
41         uint32_t count = 0;
42         std::lock_guard<std::mutex> l(listLock_);
43         for (BaseObject*& obj : finalizers_) {
44             visitor(reinterpret_cast<ObjectRef&>(obj));
45             ++count;
46         }
47         return count;
48     }
49 
50     // for : *finalizers* are not proper gc roots.
VisitGCRoots(const RootVisitor & visitor)51     void VisitGCRoots(const RootVisitor& visitor)
52     {
53         std::lock_guard<std::mutex> l(listLock_);
54         for (BaseObject*& obj : finalizables_) {
55             visitor(reinterpret_cast<ObjectRef&>(obj));
56         }
57         for (BaseObject*& obj : workingFinalizables_) {
58             visitor(reinterpret_cast<ObjectRef&>(obj));
59         }
60     }
61 
62     // mainly for fixing old pointers
VisitRawPointers(const RootVisitor & visitor)63     void VisitRawPointers(const RootVisitor& visitor)
64     {
65         std::lock_guard<std::mutex> l(listLock_);
66         for (BaseObject*& obj : finalizables_) {
67             visitor(reinterpret_cast<ObjectRef&>(obj));
68         }
69         for (BaseObject*& obj : workingFinalizables_) {
70             visitor(reinterpret_cast<ObjectRef&>(obj));
71         }
72         for (BaseObject*& obj : finalizers_) {
73             visitor(reinterpret_cast<ObjectRef&>(obj));
74         }
75     }
76 
77     // notify for finalizer processing loop, invoked after GC
78     void Notify();
79     // wait started flag set, call after create finalizerProcessor thread
80     void WaitStarted();
81 
82     void Start();
83     void Stop();
84     void Run();
85     void Init();
86     void Fini();
87     void WaitStop();
88 
89     void EnqueueFinalizables(const std::function<bool(BaseObject*)>& finalizable, uint32_t countLimit = UINT_MAX);
90     void RegisterFinalizer(BaseObject* obj);
IsRunning()91     bool IsRunning() const { return running_; }
GetTid()92     uint32_t GetTid() const { return tid_; }
93 
GetMutator()94     Mutator* GetMutator() const { return fpMutator_; }
95 
NotifyToReclaimGarbage()96     void NotifyToReclaimGarbage() { shouldReclaimHeapGarbage_.store(true); }
NotifyToFeedAllocBuffers()97     void NotifyToFeedAllocBuffers()
98     {
99         shouldFeedHungryBuffers_.store(true, std::memory_order_release);
100         Notify();
101     }
102 
103 private:
104     void NotifyStarted();
105     void Wait(uint32_t timeoutMilliSeconds);
106     void ProcessFinalizables();
107     void ProcessFinalizableList();
108     void ReclaimHeapGarbage();
109     void FeedHungryBuffers();
110 
111     std::mutex wakeLock_;
112     std::condition_variable wakeCondition_; // notify finalizer processing continue
113 
114     std::mutex startedLock_;
115     std::condition_variable startedCondition_; // notify finalizerProcessor thread is started
116     volatile bool started_;
117 
118     volatile bool running_; // Initially false and set true after finalizerProcessor thread start, set false when stop
119 
120     uint32_t iterationWaitTime_;
121 
122     // finalization
123     std::mutex listLock_;                 // lock for finalizers & finalizables & workingFinalizables
124     ManagedList<BaseObject*> finalizers_; // created finalizer record, accessed by mutator & GC
125 
126     // a dead finalizer is moved into finalizable by GC, then run finalize method by FP thread
127     ManagedList<BaseObject*> finalizables_;
128 
129     ManagedList<BaseObject*> workingFinalizables_; // FP working list, swap from finalizables
130 
131     std::atomic<bool> hasFinalizableJob_;
132     std::atomic<bool> shouldReclaimHeapGarbage_;
133     std::atomic<bool> shouldFeedHungryBuffers_;
134     #if defined(GCINFO_DEBUG) && GCINFO_DEBUG
135     // stats
136     void LogAfterProcess();
137 #endif
138     uint64_t timeProcessorBegin_;
139     uint64_t timeProcessUsed_;
140     uint64_t timeCurrentProcessBegin_;
141     uint32_t tid_ = 0;
142     pthread_t threadHandle_ = 0; // thread handle to thread
143     Mutator* fpMutator_ = nullptr;
144 };
145 } // namespace common
146 
147 #endif // COMMON_COMPONENTS_HEAP_COLLECTOR_FINALIZER_PROCESSOR_H
148