1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_MEMORY_RECLAIMER_H_ 6 #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_MEMORY_RECLAIMER_H_ 7 8 #include <memory> 9 #include <set> 10 11 #include "base/bind.h" 12 #include "base/callback.h" 13 #include "base/location.h" 14 #include "base/no_destructor.h" 15 #include "base/single_thread_task_runner.h" 16 #include "base/thread_annotations.h" 17 #include "base/time/time.h" 18 #include "base/timer/elapsed_timer.h" 19 #include "base/timer/timer.h" 20 21 namespace base { 22 23 namespace internal { 24 25 struct PartitionRootBase; 26 27 } // namespace internal 28 29 // Posts and handles memory reclaim tasks for PartitionAlloc. 30 // 31 // Thread safety: |RegisterPartition()| and |UnregisterPartition()| can be 32 // called from any thread, concurrently with reclaim. Reclaim itself runs in the 33 // context of the provided |SequencedTaskRunner|, meaning that the caller must 34 // take care of this runner being compatible with the various partitions. 35 // 36 // Singleton as this runs as long as the process is alive, and 37 // having multiple instances would be wasteful. 38 class BASE_EXPORT PartitionAllocMemoryReclaimer { 39 public: 40 static PartitionAllocMemoryReclaimer* Instance(); 41 42 // Internal. Do not use. 43 // Registers a partition to be tracked by the reclaimer. 44 void RegisterPartition(internal::PartitionRootBase* partition); 45 // Internal. Do not use. 46 // Unregisters a partition to be tracked by the reclaimer. 47 void UnregisterPartition(internal::PartitionRootBase* partition); 48 // Starts the periodic reclaim. Should be called once. 49 void Start(scoped_refptr<SequencedTaskRunner> task_runner); 50 // Triggers an explicit reclaim now. 51 void Reclaim(); 52 53 static constexpr TimeDelta kStatsRecordingTimeDelta = 54 TimeDelta::FromMinutes(5); 55 56 private: 57 PartitionAllocMemoryReclaimer(); 58 ~PartitionAllocMemoryReclaimer(); 59 void ReclaimAndReschedule(); 60 void RecordStatistics(); 61 void ResetForTesting(); 62 63 // Total time spent in |Reclaim()|. 64 bool has_called_reclaim_ = false; 65 TimeDelta total_reclaim_thread_time_; 66 // Schedules periodic |Reclaim()|. 67 std::unique_ptr<RepeatingTimer> timer_; 68 69 Lock lock_; 70 std::set<internal::PartitionRootBase*> partitions_ GUARDED_BY(lock_); 71 72 friend class NoDestructor<PartitionAllocMemoryReclaimer>; 73 friend class PartitionAllocMemoryReclaimerTest; 74 DISALLOW_COPY_AND_ASSIGN(PartitionAllocMemoryReclaimer); 75 }; 76 77 } // namespace base 78 79 #endif // BASE_ALLOCATOR_PARTITION_ALLOCATOR_MEMORY_RECLAIMER_H_ 80