Commit ae5e45c0 authored by Alexandr Ilin's avatar Alexandr Ilin Committed by Commit Bot

Convert discardable shared memory to the new shared memory API

Bug: 826213
Change-Id: Ifa1d7e3fd3625ef0161073d594f3f48aada7b7c8
Reviewed-on: https://chromium-review.googlesource.com/1019448Reviewed-by: default avatarDavid Reveman <reveman@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: Alexandr Ilin <alexilin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#553472}
parent 5b0d48d5
This diff is collapsed.
...@@ -10,7 +10,8 @@ ...@@ -10,7 +10,8 @@
#include "base/base_export.h" #include "base/base_export.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/shared_memory.h" #include "base/memory/shared_memory_mapping.h"
#include "base/memory/unsafe_shared_memory_region.h"
#include "base/threading/thread_collision_warner.h" #include "base/threading/thread_collision_warner.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "build/build_config.h" #include "build/build_config.h"
...@@ -49,7 +50,7 @@ class BASE_EXPORT DiscardableSharedMemory { ...@@ -49,7 +50,7 @@ class BASE_EXPORT DiscardableSharedMemory {
// Create a new DiscardableSharedMemory object from an existing, open shared // Create a new DiscardableSharedMemory object from an existing, open shared
// memory file. Memory must be locked. // memory file. Memory must be locked.
explicit DiscardableSharedMemory(SharedMemoryHandle handle); explicit DiscardableSharedMemory(UnsafeSharedMemoryRegion region);
// Closes any open files. // Closes any open files.
virtual ~DiscardableSharedMemory(); virtual ~DiscardableSharedMemory();
...@@ -71,14 +72,17 @@ class BASE_EXPORT DiscardableSharedMemory { ...@@ -71,14 +72,17 @@ class BASE_EXPORT DiscardableSharedMemory {
// The actual size of the mapped memory (may be larger than requested). // The actual size of the mapped memory (may be larger than requested).
size_t mapped_size() const { return mapped_size_; } size_t mapped_size() const { return mapped_size_; }
// Returns a shared memory handle for this DiscardableSharedMemory object. // Returns a duplicated shared memory region for this DiscardableSharedMemory
SharedMemoryHandle handle() const { return shared_memory_.handle(); } // object.
UnsafeSharedMemoryRegion DuplicateRegion() const {
return shared_memory_region_.Duplicate();
}
// Returns an ID for the shared memory region. This is ID of the mapped region // Returns an ID for the shared memory region. This is ID of the mapped region
// consistent across all processes and is valid as long as the region is not // consistent across all processes and is valid as long as the region is not
// unmapped. // unmapped.
const UnguessableToken& mapped_id() const { const UnguessableToken& mapped_id() const {
return shared_memory_.mapped_id(); return shared_memory_mapping_.guid();
} }
// Locks a range of memory so that it will not be purged by the system. // Locks a range of memory so that it will not be purged by the system.
...@@ -147,10 +151,24 @@ class BASE_EXPORT DiscardableSharedMemory { ...@@ -147,10 +151,24 @@ class BASE_EXPORT DiscardableSharedMemory {
bool is_owned) const; bool is_owned) const;
private: private:
// 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.
static LockResult LockPages(const UnsafeSharedMemoryRegion& region,
size_t offset,
size_t length);
// UnlockPages() is a no-op on platforms not supporting discardable pages.
static void UnlockPages(const UnsafeSharedMemoryRegion& region,
size_t offset,
size_t length);
// Virtual for tests. // Virtual for tests.
virtual Time Now() const; virtual Time Now() const;
SharedMemory shared_memory_; UnsafeSharedMemoryRegion shared_memory_region_;
WritableSharedMemoryMapping shared_memory_mapping_;
size_t mapped_size_; size_t mapped_size_;
size_t locked_page_count_; size_t locked_page_count_;
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
......
...@@ -15,14 +15,13 @@ ...@@ -15,14 +15,13 @@
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace base { namespace base {
namespace {
class TestDiscardableSharedMemory : public DiscardableSharedMemory { class TestDiscardableSharedMemory : public DiscardableSharedMemory {
public: public:
TestDiscardableSharedMemory() = default; TestDiscardableSharedMemory() = default;
explicit TestDiscardableSharedMemory(SharedMemoryHandle handle) explicit TestDiscardableSharedMemory(UnsafeSharedMemoryRegion region)
: DiscardableSharedMemory(handle) {} : DiscardableSharedMemory(std::move(region)) {}
void SetNow(Time now) { now_ = now; } void SetNow(Time now) { now_ = now; }
...@@ -50,10 +49,10 @@ TEST(DiscardableSharedMemoryTest, CreateFromHandle) { ...@@ -50,10 +49,10 @@ TEST(DiscardableSharedMemoryTest, CreateFromHandle) {
bool rv = memory1.CreateAndMap(kDataSize); bool rv = memory1.CreateAndMap(kDataSize);
ASSERT_TRUE(rv); ASSERT_TRUE(rv);
SharedMemoryHandle shared_handle = memory1.handle().Duplicate(); UnsafeSharedMemoryRegion shared_region = memory1.DuplicateRegion();
ASSERT_TRUE(shared_handle.IsValid()); ASSERT_TRUE(shared_region.IsValid());
TestDiscardableSharedMemory memory2(shared_handle); TestDiscardableSharedMemory memory2(std::move(shared_region));
rv = memory2.Map(kDataSize); rv = memory2.Map(kDataSize);
ASSERT_TRUE(rv); ASSERT_TRUE(rv);
EXPECT_TRUE(memory2.IsMemoryLocked()); EXPECT_TRUE(memory2.IsMemoryLocked());
...@@ -82,10 +81,10 @@ TEST(DiscardableSharedMemoryTest, LockAndUnlock) { ...@@ -82,10 +81,10 @@ TEST(DiscardableSharedMemoryTest, LockAndUnlock) {
EXPECT_EQ(DiscardableSharedMemory::SUCCESS, lock_rv); EXPECT_EQ(DiscardableSharedMemory::SUCCESS, lock_rv);
EXPECT_TRUE(memory1.IsMemoryLocked()); EXPECT_TRUE(memory1.IsMemoryLocked());
SharedMemoryHandle shared_handle = memory1.handle().Duplicate(); UnsafeSharedMemoryRegion shared_region = memory1.DuplicateRegion();
ASSERT_TRUE(shared_handle.IsValid()); ASSERT_TRUE(shared_region.IsValid());
TestDiscardableSharedMemory memory2(shared_handle); TestDiscardableSharedMemory memory2(std::move(shared_region));
rv = memory2.Map(kDataSize); rv = memory2.Map(kDataSize);
ASSERT_TRUE(rv); ASSERT_TRUE(rv);
...@@ -118,10 +117,10 @@ TEST(DiscardableSharedMemoryTest, Purge) { ...@@ -118,10 +117,10 @@ TEST(DiscardableSharedMemoryTest, Purge) {
bool rv = memory1.CreateAndMap(kDataSize); bool rv = memory1.CreateAndMap(kDataSize);
ASSERT_TRUE(rv); ASSERT_TRUE(rv);
SharedMemoryHandle shared_handle = memory1.handle().Duplicate(); UnsafeSharedMemoryRegion shared_region = memory1.DuplicateRegion();
ASSERT_TRUE(shared_handle.IsValid()); ASSERT_TRUE(shared_region.IsValid());
TestDiscardableSharedMemory memory2(shared_handle); TestDiscardableSharedMemory memory2(std::move(shared_region));
rv = memory2.Map(kDataSize); rv = memory2.Map(kDataSize);
ASSERT_TRUE(rv); ASSERT_TRUE(rv);
...@@ -158,10 +157,10 @@ TEST(DiscardableSharedMemoryTest, LastUsed) { ...@@ -158,10 +157,10 @@ TEST(DiscardableSharedMemoryTest, LastUsed) {
bool rv = memory1.CreateAndMap(kDataSize); bool rv = memory1.CreateAndMap(kDataSize);
ASSERT_TRUE(rv); ASSERT_TRUE(rv);
SharedMemoryHandle shared_handle = memory1.handle().Duplicate(); UnsafeSharedMemoryRegion shared_region = memory1.DuplicateRegion();
ASSERT_TRUE(shared_handle.IsValid()); ASSERT_TRUE(shared_region.IsValid());
TestDiscardableSharedMemory memory2(shared_handle); TestDiscardableSharedMemory memory2(std::move(shared_region));
rv = memory2.Map(kDataSize); rv = memory2.Map(kDataSize);
ASSERT_TRUE(rv); ASSERT_TRUE(rv);
...@@ -224,10 +223,10 @@ TEST(DiscardableSharedMemoryTest, LockShouldAlwaysFailAfterSuccessfulPurge) { ...@@ -224,10 +223,10 @@ TEST(DiscardableSharedMemoryTest, LockShouldAlwaysFailAfterSuccessfulPurge) {
bool rv = memory1.CreateAndMap(kDataSize); bool rv = memory1.CreateAndMap(kDataSize);
ASSERT_TRUE(rv); ASSERT_TRUE(rv);
SharedMemoryHandle shared_handle = memory1.handle().Duplicate(); UnsafeSharedMemoryRegion shared_region = memory1.DuplicateRegion();
ASSERT_TRUE(shared_handle.IsValid()); ASSERT_TRUE(shared_region.IsValid());
TestDiscardableSharedMemory memory2(shared_handle); TestDiscardableSharedMemory memory2(std::move(shared_region));
rv = memory2.Map(kDataSize); rv = memory2.Map(kDataSize);
ASSERT_TRUE(rv); ASSERT_TRUE(rv);
...@@ -242,16 +241,22 @@ TEST(DiscardableSharedMemoryTest, LockShouldAlwaysFailAfterSuccessfulPurge) { ...@@ -242,16 +241,22 @@ TEST(DiscardableSharedMemoryTest, LockShouldAlwaysFailAfterSuccessfulPurge) {
EXPECT_EQ(DiscardableSharedMemory::FAILED, lock_rv); EXPECT_EQ(DiscardableSharedMemory::FAILED, lock_rv);
} }
#if defined(OS_ANDROID)
TEST(DiscardableSharedMemoryTest, LockShouldFailIfPlatformLockPagesFails) { TEST(DiscardableSharedMemoryTest, LockShouldFailIfPlatformLockPagesFails) {
const uint32_t kDataSize = 1024; const uint32_t kDataSize = 1024;
DiscardableSharedMemory memory; DiscardableSharedMemory memory1;
bool rv = memory.CreateAndMap(kDataSize); bool rv1 = memory1.CreateAndMap(kDataSize);
ASSERT_TRUE(rv); ASSERT_TRUE(rv1);
base::UnsafeSharedMemoryRegion region = memory1.DuplicateRegion();
int fd = region.GetPlatformHandle();
DiscardableSharedMemory memory2(std::move(region));
bool rv2 = memory2.Map(kDataSize);
ASSERT_TRUE(rv2);
// Unlock() the first page of memory, so we can test Lock()ing it. // Unlock() the first page of memory, so we can test Lock()ing it.
memory.Unlock(0, base::GetPageSize()); memory2.Unlock(0, base::GetPageSize());
#if defined(OS_ANDROID)
// To cause ashmem_pin_region() to fail, we arrange for it to be called with // To cause ashmem_pin_region() to fail, we arrange for it to be called with
// an invalid file-descriptor, which requires a valid-looking fd (i.e. we // an invalid file-descriptor, which requires a valid-looking fd (i.e. we
// can't just Close() |memory|), but one on which the operation is invalid. // can't just Close() |memory|), but one on which the operation is invalid.
...@@ -260,15 +265,14 @@ TEST(DiscardableSharedMemoryTest, LockShouldFailIfPlatformLockPagesFails) { ...@@ -260,15 +265,14 @@ TEST(DiscardableSharedMemoryTest, LockShouldFailIfPlatformLockPagesFails) {
// that it can close, etc without errors, but on which ashmem_pin_region() // that it can close, etc without errors, but on which ashmem_pin_region()
// will fail. // will fail.
base::ScopedFD null(open("/dev/null", O_RDONLY)); base::ScopedFD null(open("/dev/null", O_RDONLY));
ASSERT_EQ(memory.handle().GetHandle(), ASSERT_EQ(fd, dup2(null.get(), fd));
dup2(null.get(), memory.handle().GetHandle()));
// Now re-Lock()ing the first page should fail. // Now re-Lock()ing the first page should fail.
DiscardableSharedMemory::LockResult lock_rv = DiscardableSharedMemory::LockResult lock_rv =
memory.Lock(0, base::GetPageSize()); memory2.Lock(0, base::GetPageSize());
EXPECT_EQ(DiscardableSharedMemory::FAILED, lock_rv); EXPECT_EQ(DiscardableSharedMemory::FAILED, lock_rv);
#endif // defined(OS_ANDROID)
} }
#endif // defined(OS_ANDROID)
TEST(DiscardableSharedMemoryTest, LockAndUnlockRange) { TEST(DiscardableSharedMemoryTest, LockAndUnlockRange) {
const uint32_t kDataSize = 32; const uint32_t kDataSize = 32;
...@@ -279,10 +283,10 @@ TEST(DiscardableSharedMemoryTest, LockAndUnlockRange) { ...@@ -279,10 +283,10 @@ TEST(DiscardableSharedMemoryTest, LockAndUnlockRange) {
bool rv = memory1.CreateAndMap(data_size_in_bytes); bool rv = memory1.CreateAndMap(data_size_in_bytes);
ASSERT_TRUE(rv); ASSERT_TRUE(rv);
SharedMemoryHandle shared_handle = memory1.handle().Duplicate(); UnsafeSharedMemoryRegion shared_region = memory1.DuplicateRegion();
ASSERT_TRUE(shared_handle.IsValid()); ASSERT_TRUE(shared_region.IsValid());
TestDiscardableSharedMemory memory2(shared_handle); TestDiscardableSharedMemory memory2(std::move(shared_region));
rv = memory2.Map(data_size_in_bytes); rv = memory2.Map(data_size_in_bytes);
ASSERT_TRUE(rv); ASSERT_TRUE(rv);
...@@ -396,10 +400,10 @@ TEST(DiscardableSharedMemoryTest, ZeroFilledPagesAfterPurge) { ...@@ -396,10 +400,10 @@ TEST(DiscardableSharedMemoryTest, ZeroFilledPagesAfterPurge) {
bool rv = memory1.CreateAndMap(kDataSize); bool rv = memory1.CreateAndMap(kDataSize);
ASSERT_TRUE(rv); ASSERT_TRUE(rv);
SharedMemoryHandle shared_handle = memory1.handle().Duplicate(); UnsafeSharedMemoryRegion shared_region = memory1.DuplicateRegion();
ASSERT_TRUE(shared_handle.IsValid()); ASSERT_TRUE(shared_region.IsValid());
TestDiscardableSharedMemory memory2(shared_handle); TestDiscardableSharedMemory memory2(std::move(shared_region));
rv = memory2.Map(kDataSize); rv = memory2.Map(kDataSize);
ASSERT_TRUE(rv); ASSERT_TRUE(rv);
...@@ -449,5 +453,4 @@ TEST(DiscardableSharedMemoryTest, TracingOwnershipEdges) { ...@@ -449,5 +453,4 @@ TEST(DiscardableSharedMemoryTest, TracingOwnershipEdges) {
// CreateWeakSharedMemoryOwnershipEdge() is fixed, crbug.com/661257. // CreateWeakSharedMemoryOwnershipEdge() is fixed, crbug.com/661257.
} }
} // namespace
} // namespace base } // namespace base
...@@ -44,6 +44,15 @@ SharedMemoryTracker::GetOrCreateSharedMemoryDump( ...@@ -44,6 +44,15 @@ SharedMemoryTracker::GetOrCreateSharedMemoryDump(
shared_memory->mapped_id(), pmd); shared_memory->mapped_id(), pmd);
} }
const trace_event::MemoryAllocatorDump*
SharedMemoryTracker::GetOrCreateSharedMemoryDump(
const SharedMemoryMapping& shared_memory,
trace_event::ProcessMemoryDump* pmd) {
return GetOrCreateSharedMemoryDumpInternal(shared_memory.raw_memory_ptr(),
shared_memory.mapped_size(),
shared_memory.guid(), pmd);
}
void SharedMemoryTracker::IncrementMemoryUsage( void SharedMemoryTracker::IncrementMemoryUsage(
const SharedMemory& shared_memory) { const SharedMemory& shared_memory) {
AutoLock hold(usages_lock_); AutoLock hold(usages_lock_);
......
...@@ -38,11 +38,14 @@ class BASE_EXPORT SharedMemoryTracker : public trace_event::MemoryDumpProvider { ...@@ -38,11 +38,14 @@ class BASE_EXPORT SharedMemoryTracker : public trace_event::MemoryDumpProvider {
static const trace_event::MemoryAllocatorDump* GetOrCreateSharedMemoryDump( static const trace_event::MemoryAllocatorDump* GetOrCreateSharedMemoryDump(
const SharedMemory* shared_memory, const SharedMemory* shared_memory,
trace_event::ProcessMemoryDump* pmd); trace_event::ProcessMemoryDump* pmd);
// We're in the middle of a refactor https://crbug.com/795291. Eventually, the
// first call will go away.
static const trace_event::MemoryAllocatorDump* GetOrCreateSharedMemoryDump(
const SharedMemoryMapping& shared_memory,
trace_event::ProcessMemoryDump* pmd);
// Records shared memory usage on valid mapping. // Records shared memory usage on valid mapping.
void IncrementMemoryUsage(const SharedMemory& shared_memory); void IncrementMemoryUsage(const SharedMemory& shared_memory);
// We're in the middle of a refactor https://crbug.com/795291. Eventually, the
// first call will go away.
void IncrementMemoryUsage(const SharedMemoryMapping& mapping); void IncrementMemoryUsage(const SharedMemoryMapping& mapping);
// Records shared memory usage on unmapping. // Records shared memory usage on unmapping.
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef BASE_MEMORY_UNSAFE_SHARED_MEMORY_REGION_H_ #ifndef BASE_MEMORY_UNSAFE_SHARED_MEMORY_REGION_H_
#define BASE_MEMORY_UNSAFE_SHARED_MEMORY_REGION_H_ #define BASE_MEMORY_UNSAFE_SHARED_MEMORY_REGION_H_
#include "base/gtest_prod_util.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/platform_shared_memory_region.h" #include "base/memory/platform_shared_memory_region.h"
#include "base/memory/shared_memory_mapping.h" #include "base/memory/shared_memory_mapping.h"
...@@ -88,8 +89,19 @@ class BASE_EXPORT UnsafeSharedMemoryRegion { ...@@ -88,8 +89,19 @@ class BASE_EXPORT UnsafeSharedMemoryRegion {
} }
private: private:
FRIEND_TEST_ALL_PREFIXES(DiscardableSharedMemoryTest,
LockShouldFailIfPlatformLockPagesFails);
friend class DiscardableSharedMemory;
explicit UnsafeSharedMemoryRegion(subtle::PlatformSharedMemoryRegion handle); explicit UnsafeSharedMemoryRegion(subtle::PlatformSharedMemoryRegion handle);
// Returns a platform shared memory handle. |this| remains the owner of the
// handle.
subtle::PlatformSharedMemoryRegion::PlatformHandle GetPlatformHandle() const {
DCHECK(IsValid());
return handle_.GetPlatformHandle();
}
subtle::PlatformSharedMemoryRegion handle_; subtle::PlatformSharedMemoryRegion handle_;
DISALLOW_COPY_AND_ASSIGN(UnsafeSharedMemoryRegion); DISALLOW_COPY_AND_ASSIGN(UnsafeSharedMemoryRegion);
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event.h"
#include "components/crash/core/common/crash_key.h" #include "components/crash/core/common/crash_key.h"
#include "mojo/public/cpp/system/platform_handle.h"
namespace discardable_memory { namespace discardable_memory {
namespace { namespace {
...@@ -357,7 +356,7 @@ ClientDiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory( ...@@ -357,7 +356,7 @@ ClientDiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory(
"ClientDiscardableSharedMemoryManager::" "ClientDiscardableSharedMemoryManager::"
"AllocateLockedDiscardableSharedMemory", "AllocateLockedDiscardableSharedMemory",
"size", size, "id", id); "size", size, "id", id);
base::SharedMemoryHandle handle; base::UnsafeSharedMemoryRegion region;
base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED); base::WaitableEvent::InitialState::NOT_SIGNALED);
base::ScopedClosureRunner event_signal_runner( base::ScopedClosureRunner event_signal_runner(
...@@ -365,11 +364,12 @@ ClientDiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory( ...@@ -365,11 +364,12 @@ ClientDiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory(
io_task_runner_->PostTask( io_task_runner_->PostTask(
FROM_HERE, FROM_HERE,
base::BindOnce(&ClientDiscardableSharedMemoryManager::AllocateOnIO, base::BindOnce(&ClientDiscardableSharedMemoryManager::AllocateOnIO,
base::Unretained(this), size, id, &handle, base::Unretained(this), size, id, &region,
std::move(event_signal_runner))); std::move(event_signal_runner)));
// Waiting until IPC has finished on the IO thread. // Waiting until IPC has finished on the IO thread.
event.Wait(); event.Wait();
auto memory = std::make_unique<base::DiscardableSharedMemory>(handle); auto memory =
std::make_unique<base::DiscardableSharedMemory>(std::move(region));
if (!memory->Map(size)) if (!memory->Map(size))
base::TerminateBecauseOutOfMemory(size); base::TerminateBecauseOutOfMemory(size);
return memory; return memory;
...@@ -378,25 +378,21 @@ ClientDiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory( ...@@ -378,25 +378,21 @@ ClientDiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory(
void ClientDiscardableSharedMemoryManager::AllocateOnIO( void ClientDiscardableSharedMemoryManager::AllocateOnIO(
size_t size, size_t size,
int32_t id, int32_t id,
base::SharedMemoryHandle* handle, base::UnsafeSharedMemoryRegion* region,
base::ScopedClosureRunner closure_runner) { base::ScopedClosureRunner closure_runner) {
(*manager_mojo_) (*manager_mojo_)
->AllocateLockedDiscardableSharedMemory( ->AllocateLockedDiscardableSharedMemory(
static_cast<uint32_t>(size), id, static_cast<uint32_t>(size), id,
base::BindOnce( base::BindOnce(
&ClientDiscardableSharedMemoryManager::AllocateCompletedOnIO, &ClientDiscardableSharedMemoryManager::AllocateCompletedOnIO,
base::Unretained(this), handle, std::move(closure_runner))); base::Unretained(this), region, std::move(closure_runner)));
} }
void ClientDiscardableSharedMemoryManager::AllocateCompletedOnIO( void ClientDiscardableSharedMemoryManager::AllocateCompletedOnIO(
base::SharedMemoryHandle* handle, base::UnsafeSharedMemoryRegion* region,
base::ScopedClosureRunner closure_runner, base::ScopedClosureRunner closure_runner,
mojo::ScopedSharedBufferHandle mojo_handle) { base::UnsafeSharedMemoryRegion ret_region) {
if (!mojo_handle.is_valid()) *region = std::move(ret_region);
return;
auto result = mojo::UnwrapSharedMemoryHandle(std::move(mojo_handle), handle,
nullptr, nullptr);
DCHECK_EQ(result, MOJO_RESULT_OK);
} }
void ClientDiscardableSharedMemoryManager::DeletedDiscardableSharedMemory( void ClientDiscardableSharedMemoryManager::DeletedDiscardableSharedMemory(
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/discardable_memory_allocator.h" #include "base/memory/discardable_memory_allocator.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/shared_memory_handle.h" #include "base/memory/unsafe_shared_memory_region.h"
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
#include "base/trace_event/memory_dump_provider.h" #include "base/trace_event/memory_dump_provider.h"
#include "components/discardable_memory/common/discardable_memory_export.h" #include "components/discardable_memory/common/discardable_memory_export.h"
...@@ -67,11 +67,11 @@ class DISCARDABLE_MEMORY_EXPORT ClientDiscardableSharedMemoryManager ...@@ -67,11 +67,11 @@ class DISCARDABLE_MEMORY_EXPORT ClientDiscardableSharedMemoryManager
AllocateLockedDiscardableSharedMemory(size_t size, int32_t id); AllocateLockedDiscardableSharedMemory(size_t size, int32_t id);
void AllocateOnIO(size_t size, void AllocateOnIO(size_t size,
int32_t id, int32_t id,
base::SharedMemoryHandle* handle, base::UnsafeSharedMemoryRegion* region,
base::ScopedClosureRunner closure_runner); base::ScopedClosureRunner closure_runner);
void AllocateCompletedOnIO(base::SharedMemoryHandle* handle, void AllocateCompletedOnIO(base::UnsafeSharedMemoryRegion* region,
base::ScopedClosureRunner closure_runner, base::ScopedClosureRunner closure_runner,
mojo::ScopedSharedBufferHandle mojo_handle); base::UnsafeSharedMemoryRegion ret_region);
void DeletedDiscardableSharedMemory(int32_t id); void DeletedDiscardableSharedMemory(int32_t id);
void MemoryUsageChanged(size_t new_bytes_allocated, void MemoryUsageChanged(size_t new_bytes_allocated,
......
...@@ -14,4 +14,8 @@ mojom("interfaces") { ...@@ -14,4 +14,8 @@ mojom("interfaces") {
get_path_info("../../../..", "abspath"), get_path_info("../../../..", "abspath"),
"//mojo/services", "//mojo/services",
] ]
public_deps = [
"//mojo/public/mojom/base",
]
} }
...@@ -4,13 +4,15 @@ ...@@ -4,13 +4,15 @@
module discardable_memory.mojom; module discardable_memory.mojom;
import "mojo/public/mojom/base/shared_memory.mojom";
// This interface is used for allocating discardable shared memory from browser // This interface is used for allocating discardable shared memory from browser
// process. For mus+ash, this service will live in mus process. // process. For mus+ash, this service will live in mus process.
interface DiscardableSharedMemoryManager { interface DiscardableSharedMemoryManager {
// Allocate a locked discardable shared memory segment. // Allocate a locked discardable shared memory segment.
AllocateLockedDiscardableSharedMemory( AllocateLockedDiscardableSharedMemory(
uint32 size, uint32 size,
int32 id) => (handle<shared_buffer>? memory); int32 id) => (mojo_base.mojom.UnsafeSharedMemoryRegion region);
// Notify manager that a memory segment has been deleted. // Notify manager that a memory segment has been deleted.
DeletedDiscardableSharedMemory(int32 id); DeletedDiscardableSharedMemory(int32 id);
}; };
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
#include "components/crash/core/common/crash_key.h" #include "components/crash/core/common/crash_key.h"
#include "components/discardable_memory/common/discardable_shared_memory_heap.h" #include "components/discardable_memory/common/discardable_shared_memory_heap.h"
#include "mojo/public/cpp/bindings/strong_binding.h" #include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/cpp/system/platform_handle.h"
#if defined(OS_LINUX) #if defined(OS_LINUX)
#include "base/files/file_path.h" #include "base/files/file_path.h"
...@@ -69,16 +68,12 @@ class MojoDiscardableSharedMemoryManagerImpl ...@@ -69,16 +68,12 @@ class MojoDiscardableSharedMemoryManagerImpl
uint32_t size, uint32_t size,
int32_t id, int32_t id,
AllocateLockedDiscardableSharedMemoryCallback callback) override { AllocateLockedDiscardableSharedMemoryCallback callback) override {
base::SharedMemoryHandle handle; base::UnsafeSharedMemoryRegion region;
mojo::ScopedSharedBufferHandle memory;
if (manager_) { if (manager_) {
manager_->AllocateLockedDiscardableSharedMemoryForClient(client_id_, size, manager_->AllocateLockedDiscardableSharedMemoryForClient(client_id_, size,
id, &handle); id, &region);
memory = mojo::WrapSharedMemoryHandle(
handle, size,
mojo::UnwrappedSharedMemoryHandleProtection::kReadWrite);
} }
std::move(callback).Run(std::move(memory)); std::move(callback).Run(std::move(region));
} }
void DeletedDiscardableSharedMemory(int32_t id) override { void DeletedDiscardableSharedMemory(int32_t id) override {
...@@ -288,11 +283,11 @@ DiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(size_t size) { ...@@ -288,11 +283,11 @@ DiscardableSharedMemoryManager::AllocateLockedDiscardableMemory(size_t size) {
// Note: Use DiscardableSharedMemoryHeap for in-process allocation // Note: Use DiscardableSharedMemoryHeap for in-process allocation
// of discardable memory if the cost of each allocation is too high. // of discardable memory if the cost of each allocation is too high.
base::SharedMemoryHandle handle; base::UnsafeSharedMemoryRegion region;
AllocateLockedDiscardableSharedMemory(kInvalidUniqueClientID, size, new_id, AllocateLockedDiscardableSharedMemory(kInvalidUniqueClientID, size, new_id,
&handle); &region);
std::unique_ptr<base::DiscardableSharedMemory> memory( std::unique_ptr<base::DiscardableSharedMemory> memory(
new base::DiscardableSharedMemory(handle)); new base::DiscardableSharedMemory(std::move(region)));
if (!memory->Map(size)) if (!memory->Map(size))
base::TerminateBecauseOutOfMemory(size); base::TerminateBecauseOutOfMemory(size);
// Close file descriptor to avoid running out. // Close file descriptor to avoid running out.
...@@ -354,9 +349,9 @@ void DiscardableSharedMemoryManager:: ...@@ -354,9 +349,9 @@ void DiscardableSharedMemoryManager::
int client_id, int client_id,
size_t size, size_t size,
int32_t id, int32_t id,
base::SharedMemoryHandle* shared_memory_handle) { base::UnsafeSharedMemoryRegion* shared_memory_region) {
AllocateLockedDiscardableSharedMemory(client_id, size, id, AllocateLockedDiscardableSharedMemory(client_id, size, id,
shared_memory_handle); shared_memory_region);
} }
void DiscardableSharedMemoryManager::ClientDeletedDiscardableSharedMemory( void DiscardableSharedMemoryManager::ClientDeletedDiscardableSharedMemory(
...@@ -443,14 +438,14 @@ void DiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory( ...@@ -443,14 +438,14 @@ void DiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory(
int client_id, int client_id,
size_t size, size_t size,
int32_t id, int32_t id,
base::SharedMemoryHandle* shared_memory_handle) { base::UnsafeSharedMemoryRegion* shared_memory_region) {
base::AutoLock lock(lock_); base::AutoLock lock(lock_);
// Make sure |id| is not already in use. // Make sure |id| is not already in use.
MemorySegmentMap& client_segments = clients_[client_id]; MemorySegmentMap& client_segments = clients_[client_id];
if (client_segments.find(id) != client_segments.end()) { if (client_segments.find(id) != client_segments.end()) {
LOG(ERROR) << "Invalid discardable shared memory ID"; LOG(ERROR) << "Invalid discardable shared memory ID";
*shared_memory_handle = base::SharedMemoryHandle(); *shared_memory_region = base::UnsafeSharedMemoryRegion();
return; return;
} }
...@@ -471,21 +466,21 @@ void DiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory( ...@@ -471,21 +466,21 @@ void DiscardableSharedMemoryManager::AllocateLockedDiscardableSharedMemory(
std::unique_ptr<base::DiscardableSharedMemory> memory( std::unique_ptr<base::DiscardableSharedMemory> memory(
new base::DiscardableSharedMemory); new base::DiscardableSharedMemory);
if (!memory->CreateAndMap(size)) { if (!memory->CreateAndMap(size)) {
*shared_memory_handle = base::SharedMemoryHandle(); *shared_memory_region = base::UnsafeSharedMemoryRegion();
return; return;
} }
base::CheckedNumeric<size_t> checked_bytes_allocated = bytes_allocated_; base::CheckedNumeric<size_t> checked_bytes_allocated = bytes_allocated_;
checked_bytes_allocated += memory->mapped_size(); checked_bytes_allocated += memory->mapped_size();
if (!checked_bytes_allocated.IsValid()) { if (!checked_bytes_allocated.IsValid()) {
*shared_memory_handle = base::SharedMemoryHandle(); *shared_memory_region = base::UnsafeSharedMemoryRegion();
return; return;
} }
bytes_allocated_ = checked_bytes_allocated.ValueOrDie(); bytes_allocated_ = checked_bytes_allocated.ValueOrDie();
BytesAllocatedChanged(bytes_allocated_); BytesAllocatedChanged(bytes_allocated_);
*shared_memory_handle = base::SharedMemory::DuplicateHandle(memory->handle()); *shared_memory_region = memory->DuplicateRegion();
// Close file descriptor to avoid running out. // Close file descriptor to avoid running out.
memory->Close(); memory->Close();
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include "base/memory/memory_coordinator_client.h" #include "base/memory/memory_coordinator_client.h"
#include "base/memory/memory_pressure_listener.h" #include "base/memory/memory_pressure_listener.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/shared_memory.h" #include "base/memory/unsafe_shared_memory_region.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_current.h" #include "base/message_loop/message_loop_current.h"
...@@ -68,12 +68,12 @@ class DISCARDABLE_MEMORY_EXPORT DiscardableSharedMemoryManager ...@@ -68,12 +68,12 @@ class DISCARDABLE_MEMORY_EXPORT DiscardableSharedMemoryManager
base::trace_event::ProcessMemoryDump* pmd) override; base::trace_event::ProcessMemoryDump* pmd) override;
// This allocates a discardable memory segment for |process_handle|. // This allocates a discardable memory segment for |process_handle|.
// A valid shared memory handle is returned on success. // A valid shared memory region is returned on success.
void AllocateLockedDiscardableSharedMemoryForClient( void AllocateLockedDiscardableSharedMemoryForClient(
int client_id, int client_id,
size_t size, size_t size,
int32_t id, int32_t id,
base::SharedMemoryHandle* shared_memory_handle); base::UnsafeSharedMemoryRegion* shared_memory_region);
// Call this to notify the manager that client process associated with // Call this to notify the manager that client process associated with
// |client_id| has deleted discardable memory segment with |id|. // |client_id| has deleted discardable memory segment with |id|.
...@@ -128,7 +128,7 @@ class DISCARDABLE_MEMORY_EXPORT DiscardableSharedMemoryManager ...@@ -128,7 +128,7 @@ class DISCARDABLE_MEMORY_EXPORT DiscardableSharedMemoryManager
int client_id, int client_id,
size_t size, size_t size,
int32_t id, int32_t id,
base::SharedMemoryHandle* shared_memory_handle); base::UnsafeSharedMemoryRegion* shared_memory_region);
void DeletedDiscardableSharedMemory(int32_t id, int client_id); void DeletedDiscardableSharedMemory(int32_t id, int client_id);
void OnMemoryPressure( void OnMemoryPressure(
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level); base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level);
......
...@@ -20,8 +20,8 @@ class TestDiscardableSharedMemory : public base::DiscardableSharedMemory { ...@@ -20,8 +20,8 @@ class TestDiscardableSharedMemory : public base::DiscardableSharedMemory {
public: public:
TestDiscardableSharedMemory() {} TestDiscardableSharedMemory() {}
explicit TestDiscardableSharedMemory(base::SharedMemoryHandle handle) explicit TestDiscardableSharedMemory(base::UnsafeSharedMemoryRegion region)
: DiscardableSharedMemory(handle) {} : DiscardableSharedMemory(std::move(region)) {}
void SetNow(base::Time now) { now_ = now; } void SetNow(base::Time now) { now_ = now; }
...@@ -75,12 +75,12 @@ TEST_F(DiscardableSharedMemoryManagerTest, AllocateForClient) { ...@@ -75,12 +75,12 @@ TEST_F(DiscardableSharedMemoryManagerTest, AllocateForClient) {
uint8_t data[kDataSize]; uint8_t data[kDataSize];
memset(data, 0x80, kDataSize); memset(data, 0x80, kDataSize);
base::SharedMemoryHandle shared_handle; base::UnsafeSharedMemoryRegion shared_region;
manager_->AllocateLockedDiscardableSharedMemoryForClient( manager_->AllocateLockedDiscardableSharedMemoryForClient(
kInvalidUniqueID, kDataSize, 0, &shared_handle); kInvalidUniqueID, kDataSize, 0, &shared_region);
ASSERT_TRUE(base::SharedMemory::IsHandleValid(shared_handle)); ASSERT_TRUE(shared_region.IsValid());
TestDiscardableSharedMemory memory(shared_handle); TestDiscardableSharedMemory memory(std::move(shared_region));
bool rv = memory.Map(kDataSize); bool rv = memory.Map(kDataSize);
ASSERT_TRUE(rv); ASSERT_TRUE(rv);
...@@ -96,21 +96,21 @@ TEST_F(DiscardableSharedMemoryManagerTest, AllocateForClient) { ...@@ -96,21 +96,21 @@ TEST_F(DiscardableSharedMemoryManagerTest, AllocateForClient) {
TEST_F(DiscardableSharedMemoryManagerTest, Purge) { TEST_F(DiscardableSharedMemoryManagerTest, Purge) {
const int kDataSize = 1024; const int kDataSize = 1024;
base::SharedMemoryHandle shared_handle1; base::UnsafeSharedMemoryRegion shared_region1;
manager_->AllocateLockedDiscardableSharedMemoryForClient( manager_->AllocateLockedDiscardableSharedMemoryForClient(
kInvalidUniqueID, kDataSize, 1, &shared_handle1); kInvalidUniqueID, kDataSize, 1, &shared_region1);
ASSERT_TRUE(base::SharedMemory::IsHandleValid(shared_handle1)); ASSERT_TRUE(shared_region1.IsValid());
TestDiscardableSharedMemory memory1(shared_handle1); TestDiscardableSharedMemory memory1(std::move(shared_region1));
bool rv = memory1.Map(kDataSize); bool rv = memory1.Map(kDataSize);
ASSERT_TRUE(rv); ASSERT_TRUE(rv);
base::SharedMemoryHandle shared_handle2; base::UnsafeSharedMemoryRegion shared_region2;
manager_->AllocateLockedDiscardableSharedMemoryForClient( manager_->AllocateLockedDiscardableSharedMemoryForClient(
kInvalidUniqueID, kDataSize, 2, &shared_handle2); kInvalidUniqueID, kDataSize, 2, &shared_region2);
ASSERT_TRUE(base::SharedMemory::IsHandleValid(shared_handle2)); ASSERT_TRUE(shared_region2.IsValid());
TestDiscardableSharedMemory memory2(shared_handle2); TestDiscardableSharedMemory memory2(std::move(shared_region2));
rv = memory2.Map(kDataSize); rv = memory2.Map(kDataSize);
ASSERT_TRUE(rv); ASSERT_TRUE(rv);
...@@ -160,12 +160,12 @@ TEST_F(DiscardableSharedMemoryManagerTest, Purge) { ...@@ -160,12 +160,12 @@ TEST_F(DiscardableSharedMemoryManagerTest, Purge) {
TEST_F(DiscardableSharedMemoryManagerTest, EnforceMemoryPolicy) { TEST_F(DiscardableSharedMemoryManagerTest, EnforceMemoryPolicy) {
const int kDataSize = 1024; const int kDataSize = 1024;
base::SharedMemoryHandle shared_handle; base::UnsafeSharedMemoryRegion shared_region;
manager_->AllocateLockedDiscardableSharedMemoryForClient( manager_->AllocateLockedDiscardableSharedMemoryForClient(
kInvalidUniqueID, kDataSize, 0, &shared_handle); kInvalidUniqueID, kDataSize, 0, &shared_region);
ASSERT_TRUE(base::SharedMemory::IsHandleValid(shared_handle)); ASSERT_TRUE(shared_region.IsValid());
TestDiscardableSharedMemory memory(shared_handle); TestDiscardableSharedMemory memory(std::move(shared_region));
bool rv = memory.Map(kDataSize); bool rv = memory.Map(kDataSize);
ASSERT_TRUE(rv); ASSERT_TRUE(rv);
...@@ -198,21 +198,21 @@ TEST_F(DiscardableSharedMemoryManagerTest, ...@@ -198,21 +198,21 @@ TEST_F(DiscardableSharedMemoryManagerTest,
ReduceMemoryAfterSegmentHasBeenDeleted) { ReduceMemoryAfterSegmentHasBeenDeleted) {
const int kDataSize = 1024; const int kDataSize = 1024;
base::SharedMemoryHandle shared_handle1; base::UnsafeSharedMemoryRegion shared_region1;
manager_->AllocateLockedDiscardableSharedMemoryForClient( manager_->AllocateLockedDiscardableSharedMemoryForClient(
kInvalidUniqueID, kDataSize, 1, &shared_handle1); kInvalidUniqueID, kDataSize, 1, &shared_region1);
ASSERT_TRUE(base::SharedMemory::IsHandleValid(shared_handle1)); ASSERT_TRUE(shared_region1.IsValid());
TestDiscardableSharedMemory memory1(shared_handle1); TestDiscardableSharedMemory memory1(std::move(shared_region1));
bool rv = memory1.Map(kDataSize); bool rv = memory1.Map(kDataSize);
ASSERT_TRUE(rv); ASSERT_TRUE(rv);
base::SharedMemoryHandle shared_handle2; base::UnsafeSharedMemoryRegion shared_region2;
manager_->AllocateLockedDiscardableSharedMemoryForClient( manager_->AllocateLockedDiscardableSharedMemoryForClient(
kInvalidUniqueID, kDataSize, 2, &shared_handle2); kInvalidUniqueID, kDataSize, 2, &shared_region2);
ASSERT_TRUE(base::SharedMemory::IsHandleValid(shared_handle2)); ASSERT_TRUE(shared_region2.IsValid());
TestDiscardableSharedMemory memory2(shared_handle2); TestDiscardableSharedMemory memory2(std::move(shared_region2));
rv = memory2.Map(kDataSize); rv = memory2.Map(kDataSize);
ASSERT_TRUE(rv); ASSERT_TRUE(rv);
...@@ -261,10 +261,10 @@ TEST_F(DiscardableSharedMemoryManagerScheduleEnforceMemoryPolicyTest, ...@@ -261,10 +261,10 @@ TEST_F(DiscardableSharedMemoryManagerScheduleEnforceMemoryPolicyTest,
SetMemoryLimitOnSimpleThread) { SetMemoryLimitOnSimpleThread) {
const int kDataSize = 1024; const int kDataSize = 1024;
base::SharedMemoryHandle shared_handle; base::UnsafeSharedMemoryRegion shared_region;
manager_->AllocateLockedDiscardableSharedMemoryForClient( manager_->AllocateLockedDiscardableSharedMemoryForClient(
kInvalidUniqueID, kDataSize, 0, &shared_handle); kInvalidUniqueID, kDataSize, 0, &shared_region);
ASSERT_TRUE(base::SharedMemory::IsHandleValid(shared_handle)); ASSERT_TRUE(shared_region.IsValid());
// Set the memory limit to a value that will require EnforceMemoryPolicy() // Set the memory limit to a value that will require EnforceMemoryPolicy()
// to be schedule on a thread without a message loop. // to be schedule on a thread without a message loop.
......
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