OLD | NEW |
| (Empty) |
1 // Copyright 2014 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 CONTENT_COMMON_HOST_DISCARDABLE_SHARED_MEMORY_MANAGER_H_ | |
6 #define CONTENT_COMMON_HOST_DISCARDABLE_SHARED_MEMORY_MANAGER_H_ | |
7 | |
8 #include <stddef.h> | |
9 #include <stdint.h> | |
10 | |
11 #include <memory> | |
12 #include <vector> | |
13 | |
14 #include "base/callback.h" | |
15 #include "base/containers/hash_tables.h" | |
16 #include "base/format_macros.h" | |
17 #include "base/macros.h" | |
18 #include "base/memory/discardable_memory_allocator.h" | |
19 #include "base/memory/discardable_shared_memory.h" | |
20 #include "base/memory/memory_coordinator_client.h" | |
21 #include "base/memory/memory_pressure_listener.h" | |
22 #include "base/memory/ref_counted.h" | |
23 #include "base/memory/shared_memory.h" | |
24 #include "base/memory/weak_ptr.h" | |
25 #include "base/process/process_handle.h" | |
26 #include "base/synchronization/lock.h" | |
27 #include "base/threading/thread_task_runner_handle.h" | |
28 #include "base/trace_event/memory_dump_provider.h" | |
29 #include "content/common/content_export.h" | |
30 | |
31 namespace content { | |
32 typedef int32_t DiscardableSharedMemoryId; | |
33 | |
34 // Implementation of DiscardableMemoryAllocator that allocates and manages | |
35 // discardable memory segments for the browser process and child processes. | |
36 // This class is thread-safe and instances can safely be used on any thread. | |
37 class CONTENT_EXPORT HostDiscardableSharedMemoryManager | |
38 : public base::DiscardableMemoryAllocator, | |
39 public base::trace_event::MemoryDumpProvider, | |
40 public base::MemoryCoordinatorClient { | |
41 public: | |
42 HostDiscardableSharedMemoryManager(); | |
43 ~HostDiscardableSharedMemoryManager() override; | |
44 | |
45 // Returns a singleton instance. | |
46 static HostDiscardableSharedMemoryManager* current(); | |
47 | |
48 // Overridden from base::DiscardableMemoryAllocator: | |
49 std::unique_ptr<base::DiscardableMemory> AllocateLockedDiscardableMemory( | |
50 size_t size) override; | |
51 | |
52 // Overridden from base::trace_event::MemoryDumpProvider: | |
53 bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, | |
54 base::trace_event::ProcessMemoryDump* pmd) override; | |
55 | |
56 // This allocates a discardable memory segment for |process_handle|. | |
57 // A valid shared memory handle is returned on success. | |
58 void AllocateLockedDiscardableSharedMemoryForChild( | |
59 base::ProcessHandle process_handle, | |
60 int child_process_id, | |
61 size_t size, | |
62 DiscardableSharedMemoryId id, | |
63 base::SharedMemoryHandle* shared_memory_handle); | |
64 | |
65 // Call this to notify the manager that child process associated with | |
66 // |child_process_id| has deleted discardable memory segment with |id|. | |
67 void ChildDeletedDiscardableSharedMemory(DiscardableSharedMemoryId id, | |
68 int child_process_id); | |
69 | |
70 // Call this to notify the manager that child process associated with | |
71 // |child_process_id| has been removed. The manager will use this to release | |
72 // memory segments allocated for child process to the OS. | |
73 void ProcessRemoved(int child_process_id); | |
74 | |
75 // The maximum number of bytes of memory that may be allocated. This will | |
76 // cause memory usage to be reduced if currently above |limit|. | |
77 void SetMemoryLimit(size_t limit); | |
78 | |
79 // Reduce memory usage if above current memory limit. | |
80 void EnforceMemoryPolicy(); | |
81 | |
82 // Returns bytes of allocated discardable memory. | |
83 size_t GetBytesAllocated(); | |
84 | |
85 private: | |
86 class MemorySegment : public base::RefCountedThreadSafe<MemorySegment> { | |
87 public: | |
88 MemorySegment(std::unique_ptr<base::DiscardableSharedMemory> memory); | |
89 | |
90 base::DiscardableSharedMemory* memory() const { return memory_.get(); } | |
91 | |
92 private: | |
93 friend class base::RefCountedThreadSafe<MemorySegment>; | |
94 | |
95 ~MemorySegment(); | |
96 | |
97 std::unique_ptr<base::DiscardableSharedMemory> memory_; | |
98 | |
99 DISALLOW_COPY_AND_ASSIGN(MemorySegment); | |
100 }; | |
101 | |
102 static bool CompareMemoryUsageTime(const scoped_refptr<MemorySegment>& a, | |
103 const scoped_refptr<MemorySegment>& b) { | |
104 // In this system, LRU memory segment is evicted first. | |
105 return a->memory()->last_known_usage() > b->memory()->last_known_usage(); | |
106 } | |
107 | |
108 // base::MemoryCoordinatorClient implementation: | |
109 void OnMemoryStateChange(base::MemoryState state) override; | |
110 | |
111 void AllocateLockedDiscardableSharedMemory( | |
112 base::ProcessHandle process_handle, | |
113 int client_process_id, | |
114 size_t size, | |
115 DiscardableSharedMemoryId id, | |
116 base::SharedMemoryHandle* shared_memory_handle); | |
117 void DeletedDiscardableSharedMemory(DiscardableSharedMemoryId id, | |
118 int client_process_id); | |
119 void OnMemoryPressure( | |
120 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level); | |
121 void ReduceMemoryUsageUntilWithinMemoryLimit(); | |
122 void ReduceMemoryUsageUntilWithinLimit(size_t limit); | |
123 void ReleaseMemory(base::DiscardableSharedMemory* memory); | |
124 void BytesAllocatedChanged(size_t new_bytes_allocated) const; | |
125 | |
126 // Virtual for tests. | |
127 virtual base::Time Now() const; | |
128 virtual void ScheduleEnforceMemoryPolicy(); | |
129 | |
130 base::Lock lock_; | |
131 typedef base::hash_map<DiscardableSharedMemoryId, | |
132 scoped_refptr<MemorySegment>> MemorySegmentMap; | |
133 typedef base::hash_map<int, MemorySegmentMap> ProcessMap; | |
134 ProcessMap processes_; | |
135 // Note: The elements in |segments_| are arranged in such a way that they form | |
136 // a heap. The LRU memory segment always first. | |
137 typedef std::vector<scoped_refptr<MemorySegment>> MemorySegmentVector; | |
138 MemorySegmentVector segments_; | |
139 size_t default_memory_limit_; | |
140 size_t memory_limit_; | |
141 size_t bytes_allocated_; | |
142 std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_; | |
143 scoped_refptr<base::SingleThreadTaskRunner> | |
144 enforce_memory_policy_task_runner_; | |
145 base::Closure enforce_memory_policy_callback_; | |
146 bool enforce_memory_policy_pending_; | |
147 base::WeakPtrFactory<HostDiscardableSharedMemoryManager> weak_ptr_factory_; | |
148 | |
149 DISALLOW_COPY_AND_ASSIGN(HostDiscardableSharedMemoryManager); | |
150 }; | |
151 | |
152 } // namespace content | |
153 | |
154 #endif // CONTENT_COMMON_HOST_DISCARDABLE_SHARED_MEMORY_MANAGER_H_ | |
OLD | NEW |