* Copyright (c) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef COMMON_COMPONENTS_HEAP_COLLECTOR_FINALIZER_PROCESSOR_H
#define COMMON_COMPONENTS_HEAP_COLLECTOR_FINALIZER_PROCESSOR_H
#include <climits>
#include <condition_variable>
#include <list>
#include <mutex>
#include "common_components/common/page_allocator.h"
#include "common_components/common/type_def.h"
#include "common_components/heap/collector/collector.h"
#include "common_components/log/log.h"
namespace common {
template<typename T>
using ManagedList = std::list<T, StdContainerAllocator<T, FINALIZER_PROCESSOR>>;
class FinalizerProcessor {
public:
FinalizerProcessor();
~FinalizerProcessor() = default;
uint32_t VisitFinalizers(const RootVisitor& visitor)
{
uint32_t count = 0;
std::lock_guard<std::mutex> l(listLock_);
for (BaseObject*& obj : finalizers_) {
visitor(reinterpret_cast<ObjectRef&>(obj));
++count;
}
return count;
}
void VisitGCRoots(const RootVisitor& visitor)
{
std::lock_guard<std::mutex> l(listLock_);
for (BaseObject*& obj : finalizables_) {
visitor(reinterpret_cast<ObjectRef&>(obj));
}
for (BaseObject*& obj : workingFinalizables_) {
visitor(reinterpret_cast<ObjectRef&>(obj));
}
}
void VisitRawPointers(const RootVisitor& visitor)
{
std::lock_guard<std::mutex> l(listLock_);
for (BaseObject*& obj : finalizables_) {
visitor(reinterpret_cast<ObjectRef&>(obj));
}
for (BaseObject*& obj : workingFinalizables_) {
visitor(reinterpret_cast<ObjectRef&>(obj));
}
for (BaseObject*& obj : finalizers_) {
visitor(reinterpret_cast<ObjectRef&>(obj));
}
}
void Notify();
void WaitStarted();
void Start();
void Stop();
void Run();
void Init();
void Fini();
void WaitStop();
void EnqueueFinalizables(const std::function<bool(BaseObject*)>& finalizable, uint32_t countLimit = UINT_MAX);
void RegisterFinalizer(BaseObject* obj);
bool IsRunning() const { return running_; }
uint32_t GetTid() const { return tid_; }
Mutator* GetMutator() const { return fpMutator_; }
void NotifyToReclaimGarbage() { shouldReclaimHeapGarbage_.store(true); }
void NotifyToFeedAllocBuffers()
{
shouldFeedHungryBuffers_.store(true, std::memory_order_release);
Notify();
}
private:
void NotifyStarted();
void Wait(uint32_t timeoutMilliSeconds);
void ProcessFinalizables();
void ProcessFinalizableList();
void ReclaimHeapGarbage();
void FeedHungryBuffers();
std::mutex wakeLock_;
std::condition_variable wakeCondition_;
std::mutex startedLock_;
std::condition_variable startedCondition_;
volatile bool started_;
volatile bool running_;
uint32_t iterationWaitTime_;
std::mutex listLock_;
ManagedList<BaseObject*> finalizers_;
ManagedList<BaseObject*> finalizables_;
ManagedList<BaseObject*> workingFinalizables_;
std::atomic<bool> hasFinalizableJob_;
std::atomic<bool> shouldReclaimHeapGarbage_;
std::atomic<bool> shouldFeedHungryBuffers_;
#if defined(GCINFO_DEBUG) && GCINFO_DEBUG
void LogAfterProcess();
#endif
uint64_t timeProcessorBegin_;
uint64_t timeProcessUsed_;
uint64_t timeCurrentProcessBegin_;
uint32_t tid_ = 0;
pthread_t threadHandle_ = 0;
Mutator* fpMutator_ = nullptr;
};
}
#endif