#include "partition_alloc/thread_cache.h"
#include <sys/types.h>
#include <algorithm>
#include <atomic>
#include <cstdint>
#include "partition_alloc/build_config.h"
#include "partition_alloc/buildflags.h"
#include "partition_alloc/internal_allocator.h"
#include "partition_alloc/partition_alloc-inl.h"
#include "partition_alloc/partition_alloc_base/component_export.h"
#include "partition_alloc/partition_alloc_base/immediate_crash.h"
#include "partition_alloc/partition_alloc_base/time/time.h"
#include "partition_alloc/partition_alloc_check.h"
#include "partition_alloc/partition_alloc_config.h"
#include "partition_alloc/partition_alloc_constants.h"
#include "partition_alloc/partition_freelist_entry.h"
#include "partition_alloc/partition_root.h"
namespace partition_alloc {
namespace {
ThreadCacheRegistry g_instance;
}
namespace tools {
uintptr_t kThreadCacheNeedleArray[kThreadCacheNeedleArraySize] = …;
}
namespace internal {
PA_COMPONENT_EXPORT(PARTITION_ALLOC) PartitionTlsKey g_thread_cache_key;
#if PA_CONFIG(THREAD_CACHE_FAST_TLS)
PA_COMPONENT_EXPORT(PARTITION_ALLOC)
thread_local ThreadCache* g_thread_cache;
#endif
}
namespace {
static std::atomic<PartitionRoot*> g_thread_cache_root;
#if PA_BUILDFLAG(IS_WIN)
void OnDllProcessDetach() {
g_thread_cache_root.load(std::memory_order_relaxed)
->settings.with_thread_cache = false;
}
#endif
static bool g_thread_cache_key_created = …;
}
uint8_t ThreadCache::global_limits_[ThreadCache::kBucketCount];
uint16_t ThreadCache::largest_active_bucket_index_ = …;
ThreadCacheRegistry& ThreadCacheRegistry::Instance() { … }
const internal::PartitionFreelistDispatcher*
ThreadCache::get_freelist_dispatcher_from_root() { … }
void ThreadCacheRegistry::RegisterThreadCache(ThreadCache* cache) { … }
void ThreadCacheRegistry::UnregisterThreadCache(ThreadCache* cache) { … }
void ThreadCacheRegistry::DumpStats(bool my_thread_only,
ThreadCacheStats* stats) { … }
void ThreadCacheRegistry::PurgeAll() { … }
void ThreadCacheRegistry::ForcePurgeAllThreadAfterForkUnsafe() { … }
void ThreadCacheRegistry::SetLargestActiveBucketIndex(
uint16_t largest_active_bucket_index) { … }
void ThreadCacheRegistry::SetThreadCacheMultiplier(float multiplier) { … }
void ThreadCacheRegistry::SetPurgingConfiguration(
const internal::base::TimeDelta min_purge_interval,
const internal::base::TimeDelta max_purge_interval,
const internal::base::TimeDelta default_purge_interval,
size_t min_cached_memory_for_purging_bytes) { … }
void ThreadCacheRegistry::RunPeriodicPurge() { … }
int64_t ThreadCacheRegistry::GetPeriodicPurgeNextIntervalInMicroseconds()
const { … }
void ThreadCacheRegistry::ResetForTesting() { … }
void ThreadCache::EnsureThreadSpecificDataInitialized() { … }
void ThreadCache::DeleteForTesting(ThreadCache* tcache) { … }
void ThreadCache::SwapForTesting(PartitionRoot* root) { … }
void ThreadCache::RemoveTombstoneForTesting() { … }
void ThreadCache::Init(PartitionRoot* root) { … }
void ThreadCache::SetGlobalLimits(PartitionRoot* root, float multiplier) { … }
void ThreadCache::SetLargestCachedSize(size_t size) { … }
ThreadCache* ThreadCache::Create(PartitionRoot* root) { … }
ThreadCache::ThreadCache(PartitionRoot* root)
: … { … }
ThreadCache::~ThreadCache() { … }
void ThreadCache::Delete(void* tcache_ptr) { … }
void* ThreadCache::operator new(size_t count) { … }
void ThreadCache::operator delete(void* ptr) { … }
ThreadCache::Bucket::Bucket() { … }
void ThreadCache::FillBucket(size_t bucket_index) { … }
void ThreadCache::ClearBucket(Bucket& bucket, size_t limit) { … }
template <bool crash_on_corruption>
void ThreadCache::ClearBucketHelper(Bucket& bucket, size_t limit) { … }
template <bool crash_on_corruption>
void ThreadCache::FreeAfter(internal::PartitionFreelistEntry* head,
size_t slot_size) { … }
void ThreadCache::ResetForTesting() { … }
size_t ThreadCache::CachedMemory() const { … }
void ThreadCache::AccumulateStats(ThreadCacheStats* stats) const { … }
void ThreadCache::SetShouldPurge() { … }
void ThreadCache::Purge() { … }
void ThreadCache::TryPurge() { … }
void ThreadCache::PurgeCurrentThread() { … }
void ThreadCache::PurgeInternal() { … }
void ThreadCache::ResetPerThreadAllocationStatsForTesting() { … }
template <bool crash_on_corruption>
void ThreadCache::PurgeInternalHelper() { … }
}