Index: base/memory/discardable_shared_memory.h |
diff --git a/base/memory/discardable_shared_memory.h b/base/memory/discardable_shared_memory.h |
index ca2accf1a2ebb51e6f027ab13882c0f1e30b0747..c69c970edc8c0d6f7dd21985c30e57d007aeb89e 100644 |
--- a/base/memory/discardable_shared_memory.h |
+++ b/base/memory/discardable_shared_memory.h |
@@ -6,18 +6,27 @@ |
#define BASE_MEMORY_DISCARDABLE_SHARED_MEMORY_H_ |
#include "base/base_export.h" |
+#include "base/logging.h" |
#include "base/memory/shared_memory.h" |
+#include "base/threading/thread_collision_warner.h" |
#include "base/time/time.h" |
+#if DCHECK_IS_ON |
+#include <set> |
+#endif |
+ |
namespace base { |
// Platform abstraction for discardable shared memory. |
+// |
+// This class is not thread-safe. Clients are responsible for synchronizing |
+// access to an instance of this class. |
class BASE_EXPORT DiscardableSharedMemory { |
public: |
DiscardableSharedMemory(); |
// Create a new DiscardableSharedMemory object from an existing, open shared |
- // memory file. |
+ // memory file. Memory must be locked. |
explicit DiscardableSharedMemory(SharedMemoryHandle handle); |
// Closes any open files. |
@@ -27,26 +36,35 @@ class BASE_EXPORT DiscardableSharedMemory { |
// Returns true on success and false on failure. |
bool CreateAndMap(size_t size); |
- // Maps the discardable memory into the caller's address space. |
+ // Maps the locked discardable memory into the caller's address space. |
// Returns true on success, false otherwise. |
bool Map(size_t size); |
// The actual size of the mapped memory (may be larger than requested). |
- size_t mapped_size() const { return shared_memory_.mapped_size(); } |
+ size_t mapped_size() const { return mapped_size_; } |
// Returns a shared memory handle for this DiscardableSharedMemory object. |
SharedMemoryHandle handle() const { return shared_memory_.handle(); } |
- // Locks the memory so that it will not be purged by the system. Returns |
- // true if successful and the memory is still resident. Locking can fail |
- // for three reasons; object might have been purged, our last known usage |
+ // Locks a range of memory so that it will not be purged by the system. |
+ // Returns true if successful and the memory is still resident. Locking can |
+ // fail for three reasons; object might have been purged, our last known usage |
// timestamp might be out of date or memory might already be locked. Last |
// know usage time is updated to the actual last usage timestamp if memory |
- // is still resident or 0 if not. |
- bool Lock(); |
- |
- // Unlock previously successfully locked memory. |
- void Unlock(); |
+ // is still resident or 0 if not. The range of memory must be unlocked. The |
+ // result of trying to lock an already locked range is undefined. |
+ // |offset| and |length| must both be a multiple of the page size as returned |
+ // by GetPageSize(). |
+ // Passing 0 for |length| means "everything onward". |
+ bool Lock(size_t offset, size_t length); |
+ |
+ // Unlock a previously successfully locked range of memory. The range of |
+ // memory must be locked. The result of trying to unlock a not |
+ // previously locked range is undefined. |
+ // |offset| and |length| must both be a multiple of the page size as returned |
+ // by GetPageSize(). |
+ // Passing 0 for |length| means "everything onward". |
+ void Unlock(size_t offset, size_t length); |
// Gets a pointer to the opened discardable memory space. Discardable memory |
// must have been mapped via Map(). |
@@ -99,6 +117,14 @@ class BASE_EXPORT DiscardableSharedMemory { |
virtual Time Now() const; |
SharedMemory shared_memory_; |
+ size_t mapped_size_; |
+ size_t locked_page_count_; |
+#if DCHECK_IS_ON |
+ std::set<size_t> locked_pages_; |
+#endif |
+ // Implementation is not thread-safe but still usable if clients are |
+ // synchronized somehow. Use a collision warner to detect incorrect usage. |
+ DFAKE_MUTEX(thread_collision_warner_); |
Time last_known_usage_; |
DISALLOW_COPY_AND_ASSIGN(DiscardableSharedMemory); |