#ifndef BASE_ALLOCATOR_PARTITION_ALLOC_SUPPORT_H_
#define BASE_ALLOCATOR_PARTITION_ALLOC_SUPPORT_H_
#include <map>
#include <string>
#include "base/allocator/partition_alloc_features.h"
#include "base/base_export.h"
#include "base/feature_list.h"
#include "base/memory/scoped_refptr.h"
#include "base/synchronization/lock.h"
#include "base/task/sequenced_task_runner.h"
#include "base/thread_annotations.h"
#include "partition_alloc/buildflags.h"
#include "partition_alloc/lightweight_quarantine_support.h"
#include "partition_alloc/partition_alloc_config.h"
#include "partition_alloc/thread_cache.h"
namespace base::allocator {
BASE_EXPORT void StartThreadCachePeriodicPurge();
BASE_EXPORT void StartMemoryReclaimer(
scoped_refptr<SequencedTaskRunner> task_runner);
BASE_EXPORT std::map<std::string, std::string> ProposeSyntheticFinchTrials();
BASE_EXPORT void InstallDanglingRawPtrChecks();
BASE_EXPORT void InstallUnretainedDanglingRawPtrChecks();
BASE_EXPORT void MakeFreeNoOp();
class BASE_EXPORT PartitionAllocSupport {
public:
struct BrpConfiguration {
bool enable_brp = false;
size_t extra_extras_size = 0;
};
void ReconfigureForTests();
void ReconfigureEarlyish(const std::string& process_type);
void ReconfigureAfterZygoteFork(const std::string& process_type);
void ReconfigureAfterFeatureListInit(
const std::string& process_type,
bool configure_dangling_pointer_detector = true);
void ReconfigureAfterTaskRunnerInit(const std::string& process_type);
void OnForegrounded(bool has_main_frame = false);
void OnBackgrounded();
#if PA_BUILDFLAG(ENABLE_DANGLING_RAW_PTR_CHECKS)
static std::string ExtractDanglingPtrSignatureForTests(
std::string stacktrace);
#endif
static PartitionAllocSupport* Get();
static BrpConfiguration GetBrpConfiguration(const std::string& process_type);
static bool ShouldEnableMemoryTagging(const std::string& process_type);
static bool ShouldEnableMemoryTaggingInRendererProcess();
static bool ShouldEnablePartitionAllocWithAdvancedChecks(
const std::string& process_type);
static ::partition_alloc::internal::SchedulerLoopQuarantineConfig
GetSchedulerLoopQuarantineConfiguration(
const std::string& process_type,
features::internal::SchedulerLoopQuarantineBranchType branch_type);
private:
PartitionAllocSupport();
base::Lock lock_;
bool called_for_tests_ GUARDED_BY(lock_) = false;
bool called_earlyish_ GUARDED_BY(lock_) = false;
bool called_after_zygote_fork_ GUARDED_BY(lock_) = false;
bool called_after_feature_list_init_ GUARDED_BY(lock_) = false;
bool called_after_thread_pool_init_ GUARDED_BY(lock_) = false;
std::string established_process_type_ GUARDED_BY(lock_) = "INVALID";
#if PA_CONFIG(THREAD_CACHE_SUPPORTED) && \
PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
size_t largest_cached_size_ =
::partition_alloc::kThreadCacheDefaultSizeThreshold;
#endif
};
BASE_EXPORT BASE_DECLARE_FEATURE(kDisableMemoryReclaimerInBackground);
class BASE_EXPORT MemoryReclaimerSupport {
public:
static MemoryReclaimerSupport& Instance();
MemoryReclaimerSupport();
~MemoryReclaimerSupport();
void Start(scoped_refptr<TaskRunner> task_runner);
void SetForegrounded(bool in_foreground);
void ResetForTesting();
bool has_pending_task_for_testing() const { return has_pending_task_; }
static TimeDelta GetInterval();
static constexpr base::TimeDelta kFirstPAPurgeOrReclaimDelay =
base::Minutes(1);
private:
void Run();
void MaybeScheduleTask(TimeDelta delay = TimeDelta());
scoped_refptr<TaskRunner> task_runner_;
bool in_foreground_ = true;
bool has_pending_task_ = false;
};
BASE_EXPORT void CheckHeapIntegrity(const void* ptr);
using partition_alloc::ScopedSchedulerLoopQuarantineExclusion;
}
#endif