Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4582)

Unified Diff: base/metrics/persistent_memory_allocator.cc

Issue 2362713002: Handle failures allocating mapped local memory. (Closed)
Patch Set: use 'enum' instead of 'units' Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/metrics/persistent_memory_allocator.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/metrics/persistent_memory_allocator.cc
diff --git a/base/metrics/persistent_memory_allocator.cc b/base/metrics/persistent_memory_allocator.cc
index dfa408f44d2be244e859727515c16d402c39ad78..fd8a73d0ad2921178fdca61e4becbd21e281c9d6 100644
--- a/base/metrics/persistent_memory_allocator.cc
+++ b/base/metrics/persistent_memory_allocator.cc
@@ -17,6 +17,7 @@
#include "base/logging.h"
#include "base/memory/shared_memory.h"
#include "base/metrics/histogram_macros.h"
+#include "base/metrics/sparse_histogram.h"
namespace {
@@ -247,14 +248,27 @@ bool PersistentMemoryAllocator::IsMemoryAcceptable(const void* base,
(page_size == 0 || size % page_size == 0 || readonly));
}
-PersistentMemoryAllocator::PersistentMemoryAllocator(
- void* base,
- size_t size,
- size_t page_size,
- uint64_t id,
- base::StringPiece name,
- bool readonly)
- : mem_base_(static_cast<char*>(base)),
+PersistentMemoryAllocator::PersistentMemoryAllocator(void* base,
+ size_t size,
+ size_t page_size,
+ uint64_t id,
+ base::StringPiece name,
+ bool readonly)
+ : PersistentMemoryAllocator(Memory(base, MEM_EXTERNAL),
+ size,
+ page_size,
+ id,
+ name,
+ readonly) {}
+
+PersistentMemoryAllocator::PersistentMemoryAllocator(Memory memory,
+ size_t size,
+ size_t page_size,
+ uint64_t id,
+ base::StringPiece name,
+ bool readonly)
+ : mem_base_(static_cast<char*>(memory.base)),
+ mem_type_(memory.type),
mem_size_(static_cast<uint32_t>(size)),
mem_page_(static_cast<uint32_t>((page_size ? page_size : size))),
readonly_(readonly),
@@ -269,7 +283,7 @@ PersistentMemoryAllocator::PersistentMemoryAllocator(
"\"queue\" is not aligned properly; must be at end of struct");
// Ensure that memory segment is of acceptable size.
- CHECK(IsMemoryAcceptable(base, size, page_size, readonly));
+ CHECK(IsMemoryAcceptable(memory.base, size, page_size, readonly));
// These atomics operate inter-process and so must be lock-free. The local
// casts are to make sure it can be evaluated at compile time to a constant.
@@ -355,7 +369,7 @@ PersistentMemoryAllocator::PersistentMemoryAllocator(
*const_cast<uint32_t*>(&mem_page_) = shared_meta()->page_size;
// Ensure that settings are still valid after the above adjustments.
- if (!IsMemoryAcceptable(base, mem_size_, mem_page_, readonly))
+ if (!IsMemoryAcceptable(memory.base, mem_size_, mem_page_, readonly))
SetCorrupt();
}
}
@@ -739,37 +753,60 @@ LocalPersistentMemoryAllocator::LocalPersistentMemoryAllocator(
size, 0, id, name, false) {}
LocalPersistentMemoryAllocator::~LocalPersistentMemoryAllocator() {
- DeallocateLocalMemory(const_cast<char*>(mem_base_), mem_size_);
+ DeallocateLocalMemory(const_cast<char*>(mem_base_), mem_size_, mem_type_);
}
// static
-void* LocalPersistentMemoryAllocator::AllocateLocalMemory(size_t size) {
+PersistentMemoryAllocator::Memory
+LocalPersistentMemoryAllocator::AllocateLocalMemory(size_t size) {
+ void* address;
+
#if defined(OS_WIN)
- void* address =
+ address =
::VirtualAlloc(nullptr, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
- DPCHECK(address);
- return address;
+ if (address)
+ return Memory(address, MEM_VIRTUAL);
+ UMA_HISTOGRAM_SPARSE_SLOWLY("UMA.LocalPersistentMemoryAllocator.Failures.Win",
+ ::GetLastError());
#elif defined(OS_POSIX)
// MAP_ANON is deprecated on Linux but MAP_ANONYMOUS is not universal on Mac.
// MAP_SHARED is not available on Linux <2.4 but required on Mac.
- void* address = ::mmap(nullptr, size, PROT_READ | PROT_WRITE,
- MAP_ANON | MAP_SHARED, -1, 0);
- DPCHECK(MAP_FAILED != address);
- return address;
+ address = ::mmap(nullptr, size, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_SHARED, -1, 0);
+ if (address != MAP_FAILED)
+ return Memory(address, MEM_VIRTUAL);
+ UMA_HISTOGRAM_SPARSE_SLOWLY(
+ "UMA.LocalPersistentMemoryAllocator.Failures.Posix", errno);
#else
#error This architecture is not (yet) supported.
#endif
+
+ // As a last resort, just allocate the memory from the heap. This will
+ // achieve the same basic result but the acquired memory has to be
+ // explicitly zeroed and thus realized immediately (i.e. all pages are
+ // added to the process now istead of only when first accessed).
+ address = malloc(size);
+ DPCHECK(address);
+ memset(address, 0, size);
+ return Memory(address, MEM_MALLOC);
}
// static
void LocalPersistentMemoryAllocator::DeallocateLocalMemory(void* memory,
- size_t size) {
+ size_t size,
+ MemoryType type) {
+ if (type == MEM_MALLOC) {
+ free(memory);
+ return;
+ }
+
+ DCHECK_EQ(MEM_VIRTUAL, type);
#if defined(OS_WIN)
BOOL success = ::VirtualFree(memory, 0, MEM_DECOMMIT);
- DPCHECK(success);
+ DCHECK(success);
#elif defined(OS_POSIX)
int result = ::munmap(memory, size);
- DPCHECK(0 == result);
+ DCHECK_EQ(0, result);
#else
#error This architecture is not (yet) supported.
#endif
@@ -783,12 +820,13 @@ SharedPersistentMemoryAllocator::SharedPersistentMemoryAllocator(
uint64_t id,
base::StringPiece name,
bool read_only)
- : PersistentMemoryAllocator(static_cast<uint8_t*>(memory->memory()),
- memory->mapped_size(),
- 0,
- id,
- name,
- read_only),
+ : PersistentMemoryAllocator(
+ Memory(static_cast<uint8_t*>(memory->memory()), MEM_SHARED),
+ memory->mapped_size(),
+ 0,
+ id,
+ name,
+ read_only),
shared_memory_(std::move(memory)) {}
SharedPersistentMemoryAllocator::~SharedPersistentMemoryAllocator() {}
@@ -809,12 +847,13 @@ FilePersistentMemoryAllocator::FilePersistentMemoryAllocator(
uint64_t id,
base::StringPiece name,
bool read_only)
- : PersistentMemoryAllocator(const_cast<uint8_t*>(file->data()),
- max_size != 0 ? max_size : file->length(),
- 0,
- id,
- name,
- read_only),
+ : PersistentMemoryAllocator(
+ Memory(const_cast<uint8_t*>(file->data()), MEM_FILE),
+ max_size != 0 ? max_size : file->length(),
+ 0,
+ id,
+ name,
+ read_only),
mapped_file_(std::move(file)) {}
FilePersistentMemoryAllocator::~FilePersistentMemoryAllocator() {}
« no previous file with comments | « base/metrics/persistent_memory_allocator.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698