Commit 42e65bf2 authored by Wez's avatar Wez Committed by Commit Bot

Break out platform-specific discardable paging into Lock/UnlockPages.

Refactor the DiscardableSharedMemory implementation to put platform-
native discardable page management in separate LockPages/UnlockPages
functions.

This isolates the platform-specific calls from internal details of the
DiscardableSharedMemory implementation, in particular the need to allow
for the space occupied by the SharedState structure.

Also corrects "lock page" platform API errors to return FAILED rather
than PURGED result, and adds some DCHECKing for "unlock page" API
errors.

Bug: 716205
Change-Id: I572d65a0304816305053669ec81c78a3461d8325
Reviewed-on: https://chromium-review.googlesource.com/574901
Commit-Queue: Wez <wez@chromium.org>
Reviewed-by: default avatarDavid Reveman <reveman@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#488027}
parent 024c77e9
......@@ -99,6 +99,39 @@ size_t AlignToPageSize(size_t size) {
return bits::Align(size, base::GetPageSize());
}
// LockPages/UnlockPages are platform-native discardable page management
// helper functions. Both expect |offset| to be specified relative to the
// base address at which |memory| is mapped, and that |offset| and |length|
// are page-aligned by the caller.
// Returns SUCCESS on platforms which do not support discardable pages.
DiscardableSharedMemory::LockResult LockPages(const SharedMemory& memory,
size_t offset,
size_t length) {
#if defined(OS_ANDROID)
SharedMemoryHandle handle = memory.handle();
if (handle.IsValid()) {
int pin_result = ashmem_pin_region(handle.GetHandle(), offset, length);
if (pin_result == ASHMEM_WAS_PURGED)
return DiscardableSharedMemory::PURGED;
if (pin_result < 0)
return DiscardableSharedMemory::FAILED;
}
#endif
return DiscardableSharedMemory::SUCCESS;
}
// UnlockPages() is a no-op on platforms not supporting discardable pages.
void UnlockPages(const SharedMemory& memory, size_t offset, size_t length) {
#if defined(OS_ANDROID)
SharedMemoryHandle handle = memory.handle();
if (handle.IsValid()) {
int unpin_result = ashmem_unpin_region(handle.GetHandle(), offset, length);
DCHECK_EQ(0, unpin_result);
}
#endif
}
} // namespace
DiscardableSharedMemory::DiscardableSharedMemory()
......@@ -221,19 +254,9 @@ DiscardableSharedMemory::LockResult DiscardableSharedMemory::Lock(
if (!length)
return PURGED;
// Pin pages if supported.
#if defined(OS_ANDROID)
SharedMemoryHandle handle = shared_memory_.handle();
if (handle.IsValid()) {
if (ashmem_pin_region(handle.GetHandle(),
AlignToPageSize(sizeof(SharedState)) + offset,
length)) {
return PURGED;
}
}
#endif
return SUCCESS;
// Ensure that the platform won't discard the required pages.
return LockPages(shared_memory_,
AlignToPageSize(sizeof(SharedState)) + offset, length);
}
void DiscardableSharedMemory::Unlock(size_t offset, size_t length) {
......@@ -243,23 +266,16 @@ void DiscardableSharedMemory::Unlock(size_t offset, size_t length) {
// Calls to this function must be synchronized properly.
DFAKE_SCOPED_LOCK(thread_collision_warner_);
// Zero for length means "everything onward".
// Passing zero for |length| means "everything onward". Note that |length| may
// still be zero after this calculation, e.g. if |mapped_size_| is zero.
if (!length)
length = AlignToPageSize(mapped_size_) - offset;
DCHECK(shared_memory_.memory());
// Unpin pages if supported.
#if defined(OS_ANDROID)
SharedMemoryHandle handle = shared_memory_.handle();
if (handle.IsValid()) {
if (ashmem_unpin_region(handle.GetHandle(),
AlignToPageSize(sizeof(SharedState)) + offset,
length)) {
DPLOG(ERROR) << "ashmem_unpin_region() failed";
}
}
#endif
// Allow the pages to be discarded by the platform, if supported.
UnlockPages(shared_memory_, AlignToPageSize(sizeof(SharedState)) + offset,
length);
size_t start = offset / base::GetPageSize();
size_t end = start + length / base::GetPageSize();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment