1*9507f98cSAndroid Build Coastguard Worker // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2*9507f98cSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*9507f98cSAndroid Build Coastguard Worker // found in the LICENSE file. See the AUTHORS file for names of contributors. 4*9507f98cSAndroid Build Coastguard Worker 5*9507f98cSAndroid Build Coastguard Worker #ifndef STORAGE_LEVELDB_UTIL_ARENA_H_ 6*9507f98cSAndroid Build Coastguard Worker #define STORAGE_LEVELDB_UTIL_ARENA_H_ 7*9507f98cSAndroid Build Coastguard Worker 8*9507f98cSAndroid Build Coastguard Worker #include <atomic> 9*9507f98cSAndroid Build Coastguard Worker #include <cassert> 10*9507f98cSAndroid Build Coastguard Worker #include <cstddef> 11*9507f98cSAndroid Build Coastguard Worker #include <cstdint> 12*9507f98cSAndroid Build Coastguard Worker #include <vector> 13*9507f98cSAndroid Build Coastguard Worker 14*9507f98cSAndroid Build Coastguard Worker namespace leveldb { 15*9507f98cSAndroid Build Coastguard Worker 16*9507f98cSAndroid Build Coastguard Worker class Arena { 17*9507f98cSAndroid Build Coastguard Worker public: 18*9507f98cSAndroid Build Coastguard Worker Arena(); 19*9507f98cSAndroid Build Coastguard Worker 20*9507f98cSAndroid Build Coastguard Worker Arena(const Arena&) = delete; 21*9507f98cSAndroid Build Coastguard Worker Arena& operator=(const Arena&) = delete; 22*9507f98cSAndroid Build Coastguard Worker 23*9507f98cSAndroid Build Coastguard Worker ~Arena(); 24*9507f98cSAndroid Build Coastguard Worker 25*9507f98cSAndroid Build Coastguard Worker // Return a pointer to a newly allocated memory block of "bytes" bytes. 26*9507f98cSAndroid Build Coastguard Worker char* Allocate(size_t bytes); 27*9507f98cSAndroid Build Coastguard Worker 28*9507f98cSAndroid Build Coastguard Worker // Allocate memory with the normal alignment guarantees provided by malloc. 29*9507f98cSAndroid Build Coastguard Worker char* AllocateAligned(size_t bytes); 30*9507f98cSAndroid Build Coastguard Worker 31*9507f98cSAndroid Build Coastguard Worker // Returns an estimate of the total memory usage of data allocated 32*9507f98cSAndroid Build Coastguard Worker // by the arena. MemoryUsage()33*9507f98cSAndroid Build Coastguard Worker size_t MemoryUsage() const { 34*9507f98cSAndroid Build Coastguard Worker return memory_usage_.load(std::memory_order_relaxed); 35*9507f98cSAndroid Build Coastguard Worker } 36*9507f98cSAndroid Build Coastguard Worker 37*9507f98cSAndroid Build Coastguard Worker private: 38*9507f98cSAndroid Build Coastguard Worker char* AllocateFallback(size_t bytes); 39*9507f98cSAndroid Build Coastguard Worker char* AllocateNewBlock(size_t block_bytes); 40*9507f98cSAndroid Build Coastguard Worker 41*9507f98cSAndroid Build Coastguard Worker // Allocation state 42*9507f98cSAndroid Build Coastguard Worker char* alloc_ptr_; 43*9507f98cSAndroid Build Coastguard Worker size_t alloc_bytes_remaining_; 44*9507f98cSAndroid Build Coastguard Worker 45*9507f98cSAndroid Build Coastguard Worker // Array of new[] allocated memory blocks 46*9507f98cSAndroid Build Coastguard Worker std::vector<char*> blocks_; 47*9507f98cSAndroid Build Coastguard Worker 48*9507f98cSAndroid Build Coastguard Worker // Total memory usage of the arena. 49*9507f98cSAndroid Build Coastguard Worker // 50*9507f98cSAndroid Build Coastguard Worker // TODO(costan): This member is accessed via atomics, but the others are 51*9507f98cSAndroid Build Coastguard Worker // accessed without any locking. Is this OK? 52*9507f98cSAndroid Build Coastguard Worker std::atomic<size_t> memory_usage_; 53*9507f98cSAndroid Build Coastguard Worker }; 54*9507f98cSAndroid Build Coastguard Worker Allocate(size_t bytes)55*9507f98cSAndroid Build Coastguard Workerinline char* Arena::Allocate(size_t bytes) { 56*9507f98cSAndroid Build Coastguard Worker // The semantics of what to return are a bit messy if we allow 57*9507f98cSAndroid Build Coastguard Worker // 0-byte allocations, so we disallow them here (we don't need 58*9507f98cSAndroid Build Coastguard Worker // them for our internal use). 59*9507f98cSAndroid Build Coastguard Worker assert(bytes > 0); 60*9507f98cSAndroid Build Coastguard Worker if (bytes <= alloc_bytes_remaining_) { 61*9507f98cSAndroid Build Coastguard Worker char* result = alloc_ptr_; 62*9507f98cSAndroid Build Coastguard Worker alloc_ptr_ += bytes; 63*9507f98cSAndroid Build Coastguard Worker alloc_bytes_remaining_ -= bytes; 64*9507f98cSAndroid Build Coastguard Worker return result; 65*9507f98cSAndroid Build Coastguard Worker } 66*9507f98cSAndroid Build Coastguard Worker return AllocateFallback(bytes); 67*9507f98cSAndroid Build Coastguard Worker } 68*9507f98cSAndroid Build Coastguard Worker 69*9507f98cSAndroid Build Coastguard Worker } // namespace leveldb 70*9507f98cSAndroid Build Coastguard Worker 71*9507f98cSAndroid Build Coastguard Worker #endif // STORAGE_LEVELDB_UTIL_ARENA_H_ 72