Skip to content

Commit

Permalink
Resolve race when getting approximate-memory-usage property
Browse files Browse the repository at this point in the history
The write operations in the table happens without holding the mutex
lock, but concurrent writes are avoided using "writers_" queue.
The Arena::MemoryUsage could access the blocks when write happens.
So, the memory usage is cached in atomic word and can be loaded
from any thread safely.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=107573379
  • Loading branch information
ssiddhartha authored and cmumford committed Dec 9, 2015
1 parent 3c9ff3c commit 706b7f8
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 12 deletions.
5 changes: 1 addition & 4 deletions db/memtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,7 @@ class MemTable {
}

// Returns an estimate of the number of bytes of data in use by this
// data structure.
//
// REQUIRES: external synchronization to prevent simultaneous
// operations on the same MemTable.
// data structure. It is safe to call when MemTable is being modified.
size_t ApproximateMemoryUsage();

// Return an iterator that yields the contents of the memtable.
Expand Down
6 changes: 3 additions & 3 deletions util/arena.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ namespace leveldb {

static const int kBlockSize = 4096;

Arena::Arena() {
blocks_memory_ = 0;
Arena::Arena() : memory_usage_(0) {
alloc_ptr_ = NULL; // First allocation will allocate a block
alloc_bytes_remaining_ = 0;
}
Expand Down Expand Up @@ -60,8 +59,9 @@ char* Arena::AllocateAligned(size_t bytes) {

char* Arena::AllocateNewBlock(size_t block_bytes) {
char* result = new char[block_bytes];
blocks_memory_ += block_bytes;
blocks_.push_back(result);
memory_usage_.NoBarrier_Store(
reinterpret_cast<void*>(MemoryUsage() + block_bytes + sizeof(char*)));
return result;
}

Expand Down
10 changes: 5 additions & 5 deletions util/arena.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include "port/port.h"

namespace leveldb {

Expand All @@ -24,10 +25,9 @@ class Arena {
char* AllocateAligned(size_t bytes);

// Returns an estimate of the total memory usage of data allocated
// by the arena (including space allocated but not yet used for user
// allocations).
// by the arena.
size_t MemoryUsage() const {
return blocks_memory_ + blocks_.capacity() * sizeof(char*);
return reinterpret_cast<uintptr_t>(memory_usage_.NoBarrier_Load());
}

private:
Expand All @@ -41,8 +41,8 @@ class Arena {
// Array of new[] allocated memory blocks
std::vector<char*> blocks_;

// Bytes of memory in blocks allocated so far
size_t blocks_memory_;
// Total memory usage of the arena.
port::AtomicPointer memory_usage_;

// No copying allowed
Arena(const Arena&);
Expand Down

0 comments on commit 706b7f8

Please sign in to comment.