| Line |
Branch |
Exec |
Source |
| 1 |
|
|
#pragma once |
| 2 |
|
|
|
| 3 |
|
|
#include <fcntl.h> |
| 4 |
|
|
#include <sys/mman.h> |
| 5 |
|
|
|
| 6 |
|
|
#include <deque> |
| 7 |
|
|
#include <fstream> |
| 8 |
|
|
#include <functional> |
| 9 |
|
|
#include <memory> |
| 10 |
|
|
#include <mutex> |
| 11 |
|
|
#include <queue> |
| 12 |
|
|
#include <set> |
| 13 |
|
|
#include <string> |
| 14 |
|
|
#include <thread> |
| 15 |
|
|
#include <unordered_map> |
| 16 |
|
|
#include <utility> |
| 17 |
|
|
#include <vector> |
| 18 |
|
|
#include "base/factory.h" |
| 19 |
|
|
#include "base/async_time.h" |
| 20 |
|
|
#include "base/bitmap.h" |
| 21 |
|
|
#include "base/counter.h" |
| 22 |
|
|
#include "base/hashtable.h" |
| 23 |
|
|
#include "base/string.h" |
| 24 |
|
|
#include "memory/malloc.h" |
| 25 |
|
|
#include "memory/shm_file.h" |
| 26 |
|
|
namespace base { |
| 27 |
|
|
|
| 28 |
|
|
class PersistSimpleMalloc : public MallocApi { |
| 29 |
|
|
public: |
| 30 |
|
|
PersistSimpleMalloc( |
| 31 |
|
|
const std::string& filename, int64 memory_size, int slab_size) |
| 32 |
|
|
: memory_size_(memory_size), slab_size_(slab_size) { |
| 33 |
|
|
bool file_exists = base::file_util::PathExists(filename); |
| 34 |
|
|
|
| 35 |
|
|
meta_data_memory_size_ = memory_size_ / slab_size_ * sizeof(uint64_t); |
| 36 |
|
|
|
| 37 |
|
|
shm_file_ = ShmFile::New(ShmFile::ConfigForMedium( |
| 38 |
|
|
"DRAM", filename, memory_size + meta_data_memory_size_)); |
| 39 |
|
|
if (!shm_file_) { |
| 40 |
|
|
file_exists = false; |
| 41 |
|
|
CHECK(base::file_util::Delete(filename, false)); |
| 42 |
|
|
shm_file_ = ShmFile::New(ShmFile::ConfigForMedium( |
| 43 |
|
|
"DRAM", filename, memory_size + meta_data_memory_size_)); |
| 44 |
|
|
CHECK(shm_file_) << filename << " " << memory_size; |
| 45 |
|
|
} |
| 46 |
|
|
Initialize(); |
| 47 |
|
|
meta_data_block_ = (uint64_t*)shm_file_->Data(); |
| 48 |
|
|
data_ = shm_file_->Data() + meta_data_memory_size_; |
| 49 |
|
|
if (!file_exists) { |
| 50 |
|
|
LOG(INFO) << "PersistSimpleMalloc: first initialization."; |
| 51 |
|
|
} else { |
| 52 |
|
|
LOG(INFO) << "PersistSimpleMalloc: Recovery from shutdown."; |
| 53 |
|
|
} |
| 54 |
|
|
LOG(WARNING) << "skip the first allocate"; |
| 55 |
|
|
allocated_.fetch_add(slab_size_); |
| 56 |
|
|
} |
| 57 |
|
|
|
| 58 |
|
|
char* New(int malloc_size) override { |
| 59 |
|
|
CHECK_EQ(malloc_size, slab_size_) << "Simple Malloc, size inconsistent"; |
| 60 |
|
|
auto offset = allocated_.fetch_add(malloc_size); |
| 61 |
|
|
nr_malloc_++; |
| 62 |
|
|
// TODO allocate |
| 63 |
|
|
if (offset + slab_size_ >= memory_size_) { |
| 64 |
|
|
offset = 0; |
| 65 |
|
|
allocated_ = 0; |
| 66 |
|
|
} |
| 67 |
|
|
CHECK_LE(offset + slab_size_, memory_size_); |
| 68 |
|
|
meta_data_block_[offset / slab_size_] = malloc_size; |
| 69 |
|
|
return data_ + offset; |
| 70 |
|
|
} |
| 71 |
|
|
|
| 72 |
|
|
bool Free(void* memory_data) override { |
| 73 |
|
|
LOG(FATAL) << "not implement"; |
| 74 |
|
|
return false; |
| 75 |
|
|
} |
| 76 |
|
|
|
| 77 |
|
|
void AddMallocs4Recovery(int64_t shm_offset) override { |
| 78 |
|
|
LOG(FATAL) << "not implement"; |
| 79 |
|
|
} |
| 80 |
|
|
|
| 81 |
|
|
std::string GetInfo() const override { |
| 82 |
|
|
std::string info; |
| 83 |
|
|
info.append(base::StringPrintf( |
| 84 |
|
|
"allocated/memory_size/util: %ld/%ld/%ld\n", |
| 85 |
|
|
allocated_.load(), |
| 86 |
|
|
memory_size_, |
| 87 |
|
|
allocated_.load() * 100 / memory_size_)); |
| 88 |
|
|
return info; |
| 89 |
|
|
} |
| 90 |
|
|
|
| 91 |
|
|
uint64_t total_malloc() const override { return nr_malloc_; } |
| 92 |
|
|
|
| 93 |
|
|
bool Healthy() const override { return true; } |
| 94 |
|
|
|
| 95 |
|
|
void GetMallocsAppend(std::vector<char*>* mallocs_data) const override { |
| 96 |
|
|
LOG(FATAL) << "not implement"; |
| 97 |
|
|
} |
| 98 |
|
|
void GetMallocsAppend(std::vector<int64>* mallocs_offset) const override { |
| 99 |
|
|
LOG(FATAL) << "not implement"; |
| 100 |
|
|
} |
| 101 |
|
|
void Initialize() override { allocated_.store(0); } |
| 102 |
|
|
|
| 103 |
|
|
char* GetMallocData(int64 offset) const override { return data_ + offset; } |
| 104 |
|
|
|
| 105 |
|
|
int GetMallocSize(int64 offset) const override { |
| 106 |
|
|
return meta_data_block_[offset / slab_size_]; |
| 107 |
|
|
} |
| 108 |
|
|
|
| 109 |
|
|
int64 GetMallocOffset(const char* data) const override { |
| 110 |
|
|
int64 offset = data - data_; |
| 111 |
|
|
CHECK(data_ <= data); |
| 112 |
|
|
CHECK(data + slab_size_ < data_ + memory_size_); |
| 113 |
|
|
return offset; |
| 114 |
|
|
} |
| 115 |
|
|
int GetMallocSize(const char* data) const override { |
| 116 |
|
|
return GetMallocSize(GetMallocOffset(data)); |
| 117 |
|
|
} |
| 118 |
|
|
|
| 119 |
|
|
private: |
| 120 |
|
|
std::unique_ptr<ShmFile> shm_file_; |
| 121 |
|
|
std::atomic<uint64_t> allocated_{0}; |
| 122 |
|
|
std::atomic<uint64_t> nr_malloc_{0}; |
| 123 |
|
|
char* data_; |
| 124 |
|
|
uint64_t* meta_data_block_; |
| 125 |
|
|
int64 memory_size_; |
| 126 |
|
|
int64 meta_data_memory_size_; |
| 127 |
|
|
int64 slab_size_; |
| 128 |
|
|
DISALLOW_COPY_AND_ASSIGN(PersistSimpleMalloc); |
| 129 |
|
|
}; |
| 130 |
|
|
|
| 131 |
|
|
template <bool PERFECT_FIT_MOD = true> |
| 132 |
|
|
class PersistMemoryPool : public MallocApi { |
| 133 |
|
|
static constexpr uint64_t kChunkSize = 2 * 1024 * 1024LL; |
| 134 |
|
|
static constexpr int kMetaDataSize = 8; |
| 135 |
|
|
|
| 136 |
|
|
class Chunk { |
| 137 |
|
|
public: |
| 138 |
|
✗ |
Chunk(char* chunk_start, uint64 chunk_id) { |
| 139 |
|
✗ |
header_ = (ChunkHeader*)chunk_start; |
| 140 |
|
✗ |
data_ = nullptr; |
| 141 |
|
✗ |
chunk_id_ = chunk_id; |
| 142 |
|
✗ |
allocated_entries_ = 0; |
| 143 |
|
✗ |
} |
| 144 |
|
|
|
| 145 |
|
✗ |
void Initialize() { header_->is_used = false; } |
| 146 |
|
|
|
| 147 |
|
✗ |
void Use(int slab_size) { |
| 148 |
|
|
// header(nr_entries) + nr_entries * slab_size < kChunkSize |
| 149 |
|
✗ |
int nr_entries = kChunkSize / slab_size; |
| 150 |
|
✗ |
nr_entries -= (nr_entries % 64); |
| 151 |
|
|
|
| 152 |
0/4
base::PersistMemoryPool<false>::Chunk::Use(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::Chunk::Use(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
while (ChunkHeader::HeaderSize(nr_entries) + nr_entries * slab_size > |
| 153 |
|
|
kChunkSize) { |
| 154 |
|
✗ |
nr_entries -= 64; |
| 155 |
|
|
} |
| 156 |
|
|
|
| 157 |
0/12
base::PersistMemoryPool<false>::Chunk::Use(int):
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
base::PersistMemoryPool<true>::Chunk::Use(int):
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
|
✗ |
CHECK_GT(nr_entries, 0); |
| 158 |
|
|
|
| 159 |
|
✗ |
header_->Initialize(slab_size, nr_entries); |
| 160 |
|
✗ |
data_ = (char*)header_ + header_->HeaderSize(); |
| 161 |
|
|
// TODO: flush the meta data |
| 162 |
|
✗ |
allocated_entries_ = 0; |
| 163 |
|
✗ |
is_recovered = true; |
| 164 |
|
✗ |
} |
| 165 |
|
|
|
| 166 |
|
|
bool ValidPointerRange(void* start, void* end) { |
| 167 |
|
|
if ((char*)end - (char*)start != header_->slab_size_) { |
| 168 |
|
|
return false; |
| 169 |
|
|
} |
| 170 |
|
|
if (start < data_ || |
| 171 |
|
|
end > data_ + header_->slab_size_ * header_->nr_entries_) { |
| 172 |
|
|
return false; |
| 173 |
|
|
} |
| 174 |
|
|
return true; |
| 175 |
|
|
} |
| 176 |
|
|
|
| 177 |
|
✗ |
void Recovery() { |
| 178 |
0/4
base::PersistMemoryPool<false>::Chunk::Recovery():
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::Chunk::Recovery():
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
if (UNLIKELY(!is_recovered.load())) { |
| 179 |
|
✗ |
allocated_entries_ = header_->bitmap_->NumberOfOnes(); |
| 180 |
|
✗ |
data_ = (char*)header_ + header_->HeaderSize(); |
| 181 |
|
✗ |
is_recovered = true; |
| 182 |
|
|
} |
| 183 |
|
✗ |
} |
| 184 |
|
|
|
| 185 |
|
✗ |
bool IsChunkUsed() const { return header_->is_used; } |
| 186 |
|
|
|
| 187 |
|
✗ |
bool Full() const { |
| 188 |
|
|
#ifdef DEBUG |
| 189 |
|
|
CHECK_EQ(header_->bitmap_->FirstZeroPos() == -1, |
| 190 |
|
|
allocated_entries_ == MaxEntryNumber()); |
| 191 |
|
|
#endif |
| 192 |
|
✗ |
return allocated_entries_ == MaxEntryNumber(); |
| 193 |
|
|
// return header_->bitmap_->FirstZeroPos() == -1; |
| 194 |
|
|
} |
| 195 |
|
|
|
| 196 |
|
✗ |
char* Malloc() { |
| 197 |
0/4
base::PersistMemoryPool<false>::Chunk::Malloc():
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::Chunk::Malloc():
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
base::AutoLock lock(lock_); |
| 198 |
0/4
base::PersistMemoryPool<false>::Chunk::Malloc():
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::Chunk::Malloc():
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
Recovery(); |
| 199 |
|
✗ |
int entry_id = header_->bitmap_->SetZeroPos(); |
| 200 |
0/4
base::PersistMemoryPool<false>::Chunk::Malloc():
✗ Branch 0 not taken.
✗ Branch 1 not taken.
base::PersistMemoryPool<true>::Chunk::Malloc():
✗ Branch 0 not taken.
✗ Branch 1 not taken.
|
✗ |
if (entry_id == -1) |
| 201 |
|
✗ |
return nullptr; |
| 202 |
|
✗ |
allocated_entries_++; |
| 203 |
|
✗ |
return Entry(entry_id); |
| 204 |
|
✗ |
} |
| 205 |
|
|
|
| 206 |
|
✗ |
void Free(void* memory_data) { |
| 207 |
0/4
base::PersistMemoryPool<false>::Chunk::Free(void*):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::Chunk::Free(void*):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
base::AutoLock lock(lock_); |
| 208 |
0/4
base::PersistMemoryPool<false>::Chunk::Free(void*):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::Chunk::Free(void*):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
Recovery(); |
| 209 |
|
|
#ifdef DEBUG |
| 210 |
|
|
CHECK_LE(slab_size_ + (char*)memory_data, data_ + kChunkSize); |
| 211 |
|
|
CHECK_GE((char*)memory_data, data_); |
| 212 |
|
|
CHECK(header_->bitmap_->Get(EntryId(memory_data)) == false); |
| 213 |
|
|
#endif |
| 214 |
|
✗ |
allocated_entries_--; |
| 215 |
|
✗ |
header_->bitmap_->Clear(EntryId(memory_data)); |
| 216 |
|
✗ |
} |
| 217 |
|
|
|
| 218 |
|
✗ |
int SlabSize() const { return header_->slab_size_; } |
| 219 |
|
|
|
| 220 |
|
✗ |
int AllocatedEntryNumber() const { return allocated_entries_; } |
| 221 |
|
|
|
| 222 |
|
|
std::vector<int> GetMallocedIds() const { |
| 223 |
|
|
std::vector<int> return_id; |
| 224 |
|
|
for (int i = 0; i < MaxEntryNumber(); i++) |
| 225 |
|
|
if (header_->bitmap_->Get(i)) { |
| 226 |
|
|
return_id.push_back(i); |
| 227 |
|
|
} |
| 228 |
|
|
CHECK_EQ(return_id.size(), allocated_entries_) |
| 229 |
|
|
<< fmt::format("chunk id is {}", chunk_id_); |
| 230 |
|
|
return return_id; |
| 231 |
|
|
} |
| 232 |
|
|
|
| 233 |
|
✗ |
std::vector<char*> GetMallocedData() const { |
| 234 |
|
✗ |
std::vector<char*> return_data; |
| 235 |
0/4
base::PersistMemoryPool<false>::Chunk::GetMallocedData() const:
✗ Branch 0 not taken.
✗ Branch 1 not taken.
base::PersistMemoryPool<true>::Chunk::GetMallocedData() const:
✗ Branch 0 not taken.
✗ Branch 1 not taken.
|
✗ |
for (int i = 0; i < MaxEntryNumber(); i++) |
| 236 |
0/4
base::PersistMemoryPool<false>::Chunk::GetMallocedData() const:
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::Chunk::GetMallocedData() const:
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
if (header_->bitmap_->Get(i)) { |
| 237 |
0/4
base::PersistMemoryPool<false>::Chunk::GetMallocedData() const:
✗ Branch 2 not taken.
✗ Branch 3 not taken.
base::PersistMemoryPool<true>::Chunk::GetMallocedData() const:
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
✗ |
return_data.push_back(Entry(i)); |
| 238 |
|
|
} |
| 239 |
0/16
base::PersistMemoryPool<false>::Chunk::GetMallocedData() const:
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
base::PersistMemoryPool<true>::Chunk::GetMallocedData() const:
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
|
✗ |
CHECK_EQ(return_data.size(), allocated_entries_) |
| 240 |
0/8
base::PersistMemoryPool<false>::Chunk::GetMallocedData() const:
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
base::PersistMemoryPool<true>::Chunk::GetMallocedData() const:
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
✗ |
<< fmt::format("chunk id is {}", chunk_id_); |
| 241 |
|
✗ |
return return_data; |
| 242 |
|
✗ |
} |
| 243 |
|
|
|
| 244 |
|
|
private: |
| 245 |
|
✗ |
ALWAYS_INLINE int MaxEntryNumber() const { return header_->nr_entries_; } |
| 246 |
|
|
|
| 247 |
|
✗ |
int EntryId(void* memory_data) { |
| 248 |
|
|
#ifdef DEBUG |
| 249 |
|
|
CHECK_EQ((memory_data - data_) % SlabSize(), 0); |
| 250 |
|
|
#endif |
| 251 |
|
✗ |
return ((char*)memory_data - data_) / SlabSize(); |
| 252 |
|
|
} |
| 253 |
|
|
|
| 254 |
|
✗ |
char* Entry(int entry_id) const { |
| 255 |
|
|
#ifdef DEBUG |
| 256 |
|
|
CHECK_GE(entry_id, 0); |
| 257 |
|
|
CHECK_LT(entry_id, MaxEntryNumber()); |
| 258 |
|
|
#endif |
| 259 |
|
✗ |
return data_ + entry_id * SlabSize(); |
| 260 |
|
|
} |
| 261 |
|
|
|
| 262 |
|
|
struct ChunkHeader { |
| 263 |
|
✗ |
void Initialize(int slab_size, int nr_entries) { |
| 264 |
|
✗ |
slab_size_ = slab_size; |
| 265 |
|
✗ |
nr_entries_ = nr_entries; |
| 266 |
0/4
base::PersistMemoryPool<false>::Chunk::ChunkHeader::Initialize(int, int):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
base::PersistMemoryPool<true>::Chunk::ChunkHeader::Initialize(int, int):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
✗ |
new (bitmap_) BitMap(nr_entries); |
| 267 |
|
✗ |
bitmap_->Clear(); |
| 268 |
|
✗ |
is_used = true; |
| 269 |
|
✗ |
} |
| 270 |
|
|
|
| 271 |
|
|
bool is_used = false; |
| 272 |
|
|
int slab_size_; |
| 273 |
|
|
int nr_entries_; |
| 274 |
|
|
bool allocated; |
| 275 |
|
|
base::BitMap bitmap_[0]; // bitmap_ must be always in the tail |
| 276 |
|
|
|
| 277 |
|
✗ |
size_t HeaderSize() const { |
| 278 |
|
✗ |
return sizeof(ChunkHeader) + base::BitMap::MemorySize(nr_entries_); |
| 279 |
|
|
} |
| 280 |
|
✗ |
static size_t HeaderSize(int nr_entires) { |
| 281 |
|
✗ |
return sizeof(ChunkHeader) + base::BitMap::MemorySize(nr_entires); |
| 282 |
|
|
} |
| 283 |
|
|
DISALLOW_COPY_AND_ASSIGN(ChunkHeader); |
| 284 |
|
|
}; |
| 285 |
|
|
ChunkHeader* header_; |
| 286 |
|
|
char* data_; |
| 287 |
|
|
std::atomic_bool is_recovered = false; |
| 288 |
|
|
int allocated_entries_; |
| 289 |
|
|
uint64 chunk_id_; |
| 290 |
|
|
base::Lock lock_; |
| 291 |
|
|
DISALLOW_COPY_AND_ASSIGN(Chunk); |
| 292 |
|
|
}; |
| 293 |
|
|
|
| 294 |
|
|
public: |
| 295 |
|
✗ |
PersistMemoryPool(const std::string& filename, |
| 296 |
|
|
int64 memory_size, |
| 297 |
|
|
const std::vector<int>& slab_sizes) |
| 298 |
0/8
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
|
✗ |
: allocated_slab_sizes_(slab_sizes.begin(), slab_sizes.end()) { |
| 299 |
0/4
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
bool file_exists = base::file_util::PathExists(filename); |
| 300 |
0/12
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
✗ |
shm_file_ = |
| 301 |
|
|
ShmFile::New(ShmFile::ConfigForMedium("DRAM", filename, memory_size)); |
| 302 |
0/4
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
if (!shm_file_) { |
| 303 |
|
✗ |
file_exists = false; |
| 304 |
0/28
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
|
✗ |
CHECK(base::file_util::Delete(filename, false)); |
| 305 |
0/12
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
|
✗ |
shm_file_ = |
| 306 |
|
|
ShmFile::New(ShmFile::ConfigForMedium("DRAM", filename, memory_size)); |
| 307 |
0/36
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
|
✗ |
CHECK(shm_file_) << filename << " " << memory_size; |
| 308 |
|
|
} |
| 309 |
|
|
|
| 310 |
|
✗ |
memory_size -= memory_size % kChunkSize; |
| 311 |
|
✗ |
nr_chunks_ = memory_size / kChunkSize; |
| 312 |
|
|
|
| 313 |
0/16
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
|
✗ |
CHECK_GE(nr_chunks_, slab_sizes.size()); |
| 314 |
|
|
|
| 315 |
0/4
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
|
✗ |
for (int64 i = 0; i < nr_chunks_; i++) { |
| 316 |
0/8
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
|
✗ |
chunks_.push_back(new Chunk(shm_file_->Data() + i * kChunkSize, i)); |
| 317 |
|
|
} |
| 318 |
|
|
|
| 319 |
0/4
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 4 not taken.
✗ Branch 5 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
✗ |
for (auto slab : slab_sizes) { |
| 320 |
0/12
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
|
✗ |
size_to_chunks_[slab] = new std::deque<Chunk*>(); |
| 321 |
|
|
} |
| 322 |
|
|
|
| 323 |
0/12
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
✗ |
if (!file_exists || !Valid()) { |
| 324 |
0/12
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
|
✗ |
LOG(INFO) << "PersistMemoryPool: first initialization."; |
| 325 |
0/4
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
|
✗ |
for (int i = 0; i < nr_chunks_; i++) { |
| 326 |
|
✗ |
chunks_[i]->Initialize(); |
| 327 |
0/4
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
✗ |
free_chunks_.push_back(chunks_[i]); |
| 328 |
|
|
} |
| 329 |
|
✗ |
return; |
| 330 |
|
|
} |
| 331 |
0/12
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
|
✗ |
LOG(INFO) << "PersistMemoryPool: Recovery from shutdown."; |
| 332 |
0/4
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
|
✗ |
for (int i = 0; i < nr_chunks_; i++) { |
| 333 |
|
✗ |
auto each = chunks_[i]; |
| 334 |
0/4
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
if (each->IsChunkUsed()) { |
| 335 |
0/4
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
✗ |
auto it = size_to_chunks_.find(each->SlabSize()); |
| 336 |
0/8
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
✗ |
size_to_chunks_[each->SlabSize()]->push_back(each); |
| 337 |
0/4
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
each->Recovery(); |
| 338 |
0/12
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
|
✗ |
LOG(INFO) << "each->AllocatedEntryNumber() = " |
| 339 |
0/4
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
✗ |
<< each->AllocatedEntryNumber(); |
| 340 |
|
✗ |
total_malloc_ += each->AllocatedEntryNumber(); |
| 341 |
|
|
} else { |
| 342 |
0/4
base::PersistMemoryPool<false>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::PersistMemoryPool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, long, std::vector<int, std::allocator<int> > const&):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
free_chunks_.push_back(each); |
| 343 |
|
|
} |
| 344 |
|
|
} |
| 345 |
|
✗ |
} |
| 346 |
|
|
|
| 347 |
|
✗ |
bool Valid() const { return true; } |
| 348 |
|
|
|
| 349 |
|
✗ |
char* New(int memory_size) override { |
| 350 |
|
|
if (PERFECT_FIT_MOD) { |
| 351 |
|
|
#ifdef DEBUG |
| 352 |
|
|
CHECK(allocated_slab_sizes_.find(memory_size) != |
| 353 |
|
|
allocated_slab_sizes_.end()); |
| 354 |
|
|
#endif |
| 355 |
|
✗ |
return NewInternal(memory_size); |
| 356 |
|
|
} else { |
| 357 |
|
|
auto iter = |
| 358 |
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
allocated_slab_sizes_.lower_bound(kMetaDataSize + memory_size); |
| 359 |
0/12
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
|
✗ |
CHECK(iter != allocated_slab_sizes_.end()); |
| 360 |
0/2
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
✗ |
char* ptr = NewInternal(*iter); |
| 361 |
|
✗ |
*(int*)ptr = memory_size; |
| 362 |
|
✗ |
return ptr + kMetaDataSize; |
| 363 |
|
|
} |
| 364 |
|
|
} |
| 365 |
|
|
|
| 366 |
|
✗ |
char* NewInternal(int slab_size) { |
| 367 |
|
|
// TODO: fine grained lock |
| 368 |
0/4
base::PersistMemoryPool<false>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
base::AutoLock lock(lock_); |
| 369 |
|
✗ |
void* return_ptr = nullptr; |
| 370 |
|
|
|
| 371 |
|
✗ |
Chunk* last_used_chunk = nullptr; |
| 372 |
0/4
base::PersistMemoryPool<false>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
auto iter = size_to_last_used_chunk_.find(slab_size); |
| 373 |
0/4
base::PersistMemoryPool<false>::NewInternal(int):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
base::PersistMemoryPool<true>::NewInternal(int):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
✗ |
if (iter != size_to_last_used_chunk_.end()) |
| 374 |
|
✗ |
last_used_chunk = iter->second; |
| 375 |
|
|
|
| 376 |
0/16
base::PersistMemoryPool<false>::NewInternal(int):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
base::PersistMemoryPool<true>::NewInternal(int):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
|
✗ |
if (last_used_chunk && !last_used_chunk->Full()) { |
| 377 |
0/4
base::PersistMemoryPool<false>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
return_ptr = last_used_chunk->Malloc(); |
| 378 |
0/24
base::PersistMemoryPool<false>::NewInternal(int):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
base::PersistMemoryPool<true>::NewInternal(int):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
|
✗ |
CHECK(return_ptr); |
| 379 |
0/4
base::PersistMemoryPool<false>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
} else if (!free_chunks_.empty()) { |
| 380 |
|
✗ |
auto front = free_chunks_.front(); |
| 381 |
|
✗ |
free_chunks_.pop_front(); |
| 382 |
0/4
base::PersistMemoryPool<false>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
front->Use(slab_size); |
| 383 |
0/4
base::PersistMemoryPool<false>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
auto chunks = size_to_chunks_[slab_size]; |
| 384 |
0/4
base::PersistMemoryPool<false>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
chunks->push_back(front); |
| 385 |
0/4
base::PersistMemoryPool<false>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
size_to_last_used_chunk_[slab_size] = front; |
| 386 |
0/4
base::PersistMemoryPool<false>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
return_ptr = front->Malloc(); |
| 387 |
|
|
} else { |
| 388 |
0/4
base::PersistMemoryPool<false>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
auto chunks = size_to_chunks_[slab_size]; |
| 389 |
0/4
base::PersistMemoryPool<false>::NewInternal(int):
✗ Branch 5 not taken.
✗ Branch 6 not taken.
base::PersistMemoryPool<true>::NewInternal(int):
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
✗ |
for (auto chunk : *chunks) { |
| 390 |
0/8
base::PersistMemoryPool<false>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
base::PersistMemoryPool<true>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
✗ |
if (chunk->Full()) |
| 391 |
|
✗ |
continue; |
| 392 |
0/4
base::PersistMemoryPool<false>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
return_ptr = chunk->Malloc(); |
| 393 |
|
✗ |
goto final; |
| 394 |
|
|
} |
| 395 |
0/12
base::PersistMemoryPool<false>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
base::PersistMemoryPool<true>::NewInternal(int):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
|
✗ |
LOG(FATAL) << fmt::format( |
| 396 |
0/4
base::PersistMemoryPool<false>::NewInternal(int):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
base::PersistMemoryPool<true>::NewInternal(int):
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
✗ |
"Persist Memory Pool OOM, total_malloc={}", total_malloc_.load()); |
| 397 |
|
|
} |
| 398 |
|
✗ |
final: |
| 399 |
0/24
base::PersistMemoryPool<false>::NewInternal(int):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
base::PersistMemoryPool<true>::NewInternal(int):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
|
✗ |
CHECK(return_ptr); |
| 400 |
|
✗ |
total_malloc_++; |
| 401 |
|
✗ |
return (char*)return_ptr; |
| 402 |
|
✗ |
} |
| 403 |
|
|
|
| 404 |
|
✗ |
bool Free(void* memory_data) override { |
| 405 |
|
|
if (!PERFECT_FIT_MOD) |
| 406 |
|
✗ |
memory_data = (char*)memory_data - kMetaDataSize; |
| 407 |
|
|
|
| 408 |
|
✗ |
int chunk_id = GetChunkID(memory_data); |
| 409 |
0/12
base::PersistMemoryPool<false>::Free(void*):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
base::PersistMemoryPool<true>::Free(void*):
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
✗ |
if (0 <= chunk_id && chunk_id < chunks_.size()) { |
| 410 |
|
✗ |
chunks_[chunk_id]->Free(memory_data); |
| 411 |
|
✗ |
total_malloc_--; |
| 412 |
|
✗ |
return true; |
| 413 |
|
|
} else { |
| 414 |
|
✗ |
return false; |
| 415 |
|
|
} |
| 416 |
|
|
} |
| 417 |
|
✗ |
void GetMallocsAppend(std::vector<char*>* mallocs_data) const override { |
| 418 |
0/4
base::PersistMemoryPool<false>::GetMallocsAppend(std::vector<char*, std::allocator<char*> >*) const:
✗ Branch 6 not taken.
✗ Branch 7 not taken.
base::PersistMemoryPool<true>::GetMallocsAppend(std::vector<char*, std::allocator<char*> >*) const:
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
✗ |
for (auto chunk : chunks_) { |
| 419 |
0/4
base::PersistMemoryPool<false>::GetMallocsAppend(std::vector<char*, std::allocator<char*> >*) const:
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::GetMallocsAppend(std::vector<char*, std::allocator<char*> >*) const:
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
auto chunk_data = chunk->GetMallocedData(); |
| 420 |
0/4
base::PersistMemoryPool<false>::GetMallocsAppend(std::vector<char*, std::allocator<char*> >*) const:
✗ Branch 4 not taken.
✗ Branch 5 not taken.
base::PersistMemoryPool<true>::GetMallocsAppend(std::vector<char*, std::allocator<char*> >*) const:
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
✗ |
for (char* each : chunk_data) { |
| 421 |
|
|
if (PERFECT_FIT_MOD) |
| 422 |
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
mallocs_data->push_back(each); |
| 423 |
|
|
else |
| 424 |
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
mallocs_data->push_back((char*)each + kMetaDataSize); |
| 425 |
|
|
} |
| 426 |
|
|
} |
| 427 |
|
✗ |
} |
| 428 |
|
✗ |
void GetMallocsAppend(std::vector<int64>* mallocs_offset) const override { |
| 429 |
|
✗ |
std::vector<char*> mallocs_data; |
| 430 |
0/4
base::PersistMemoryPool<false>::GetMallocsAppend(std::vector<long, std::allocator<long> >*) const:
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::GetMallocsAppend(std::vector<long, std::allocator<long> >*) const:
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
GetMallocsAppend(&mallocs_data); |
| 431 |
0/4
base::PersistMemoryPool<false>::GetMallocsAppend(std::vector<long, std::allocator<long> >*) const:
✗ Branch 4 not taken.
✗ Branch 5 not taken.
base::PersistMemoryPool<true>::GetMallocsAppend(std::vector<long, std::allocator<long> >*) const:
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
✗ |
for (auto each : mallocs_data) { |
| 432 |
0/4
base::PersistMemoryPool<false>::GetMallocsAppend(std::vector<long, std::allocator<long> >*) const:
✗ Branch 3 not taken.
✗ Branch 4 not taken.
base::PersistMemoryPool<true>::GetMallocsAppend(std::vector<long, std::allocator<long> >*) const:
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
✗ |
mallocs_offset->push_back(each - shm_file_->Data()); |
| 433 |
|
|
} |
| 434 |
|
✗ |
} |
| 435 |
|
✗ |
void Initialize() override {} |
| 436 |
|
|
|
| 437 |
|
✗ |
std::string GetInfo() const override { |
| 438 |
|
✗ |
uint64 malloced_bytes = 0; |
| 439 |
|
✗ |
uint64 malloced_chunk = 0; |
| 440 |
0/4
base::PersistMemoryPool<false>::GetInfo[abi:cxx11]() const:
✗ Branch 5 not taken.
✗ Branch 6 not taken.
base::PersistMemoryPool<true>::GetInfo[abi:cxx11]() const:
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
✗ |
for (auto each : chunks_) { |
| 441 |
0/4
base::PersistMemoryPool<false>::GetInfo[abi:cxx11]() const:
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::GetInfo[abi:cxx11]() const:
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
if (each->IsChunkUsed()) { |
| 442 |
|
✗ |
malloced_bytes += each->AllocatedEntryNumber() * each->SlabSize(); |
| 443 |
|
✗ |
malloced_chunk++; |
| 444 |
|
|
} |
| 445 |
|
|
} |
| 446 |
|
|
return base::SFormat( |
| 447 |
|
|
"[PersistMemoryPool] " |
| 448 |
|
|
"Use {} of {} chunks, Util {} %", |
| 449 |
|
|
malloced_chunk, |
| 450 |
0/4
base::PersistMemoryPool<false>::GetInfo[abi:cxx11]() const:
✗ Branch 1 not taken.
✗ Branch 2 not taken.
base::PersistMemoryPool<true>::GetInfo[abi:cxx11]() const:
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
chunks_.size(), |
| 451 |
0/4
base::PersistMemoryPool<false>::GetInfo[abi:cxx11]() const:
✗ Branch 3 not taken.
✗ Branch 4 not taken.
base::PersistMemoryPool<true>::GetInfo[abi:cxx11]() const:
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
✗ |
100 * malloced_bytes / (kChunkSize * chunks_.size())); |
| 452 |
|
|
} |
| 453 |
|
|
|
| 454 |
|
✗ |
char* GetMallocData(int64 offset) const override { |
| 455 |
|
✗ |
return shm_file_->Data() + offset; |
| 456 |
|
|
} |
| 457 |
|
|
|
| 458 |
|
✗ |
int GetMallocSize(int64 offset) const override { |
| 459 |
|
✗ |
return GetMallocSize(GetMallocData(offset)); |
| 460 |
|
|
} |
| 461 |
|
|
|
| 462 |
|
✗ |
int64 GetMallocOffset(const char* data) const override { |
| 463 |
|
✗ |
auto ret = data - shm_file_->Data(); |
| 464 |
|
|
// see cache.SetShmMallocOffset |
| 465 |
0/16
base::PersistMemoryPool<false>::GetMallocOffset(char const*) const:
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
base::PersistMemoryPool<true>::GetMallocOffset(char const*) const:
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
|
✗ |
CHECK_EQ((ret >> 3) << 3, ret); |
| 466 |
|
✗ |
return ret; |
| 467 |
|
|
} |
| 468 |
|
|
|
| 469 |
|
✗ |
int GetMallocSize(const char* data) const override { |
| 470 |
|
|
if (PERFECT_FIT_MOD) |
| 471 |
|
✗ |
return chunks_[GetChunkID(data)]->SlabSize(); |
| 472 |
|
|
else |
| 473 |
|
✗ |
return *(int*)(data - kMetaDataSize); |
| 474 |
|
|
} |
| 475 |
|
|
|
| 476 |
|
✗ |
uint64_t total_malloc() const override { return total_malloc_; } |
| 477 |
|
|
|
| 478 |
|
✗ |
~PersistMemoryPool() override { |
| 479 |
0/4
base::PersistMemoryPool<false>::~PersistMemoryPool():
✗ Branch 4 not taken.
✗ Branch 5 not taken.
base::PersistMemoryPool<true>::~PersistMemoryPool():
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
✗ |
for (auto p : chunks_) { |
| 480 |
0/4
base::PersistMemoryPool<false>::~PersistMemoryPool():
✗ Branch 0 not taken.
✗ Branch 1 not taken.
base::PersistMemoryPool<true>::~PersistMemoryPool():
✗ Branch 0 not taken.
✗ Branch 1 not taken.
|
✗ |
delete p; |
| 481 |
|
|
} |
| 482 |
0/4
base::PersistMemoryPool<false>::~PersistMemoryPool():
✗ Branch 7 not taken.
✗ Branch 8 not taken.
base::PersistMemoryPool<true>::~PersistMemoryPool():
✗ Branch 7 not taken.
✗ Branch 8 not taken.
|
✗ |
for (auto [size, q] : size_to_chunks_) { |
| 483 |
0/4
base::PersistMemoryPool<false>::~PersistMemoryPool():
✗ Branch 0 not taken.
✗ Branch 1 not taken.
base::PersistMemoryPool<true>::~PersistMemoryPool():
✗ Branch 0 not taken.
✗ Branch 1 not taken.
|
✗ |
delete q; |
| 484 |
|
|
} |
| 485 |
|
✗ |
} |
| 486 |
|
|
|
| 487 |
|
✗ |
bool Healthy() const { return true; } |
| 488 |
|
✗ |
void AddMallocs4Recovery(int64_t shm_offset) { |
| 489 |
0/20
base::PersistMemoryPool<false>::AddMallocs4Recovery(long):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
base::PersistMemoryPool<true>::AddMallocs4Recovery(long):
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
|
✗ |
RECSTORE_LOG_EVERY_MS(ERROR, 1000) << "AddMallocs4Recovery not implement"; |
| 490 |
|
✗ |
} |
| 491 |
|
|
|
| 492 |
|
|
private: |
| 493 |
|
✗ |
int64 GetChunkID(void* data) const { return GetChunkID((const char*)data); } |
| 494 |
|
✗ |
int64 GetChunkID(const char* data) const { |
| 495 |
|
✗ |
return GetChunkID(data - shm_file_->Data()); |
| 496 |
|
|
} |
| 497 |
|
|
|
| 498 |
|
✗ |
int64 GetChunkID(int64 offset) const { return offset / kChunkSize; } |
| 499 |
|
|
|
| 500 |
|
|
private: |
| 501 |
|
|
std::unique_ptr<ShmFile> shm_file_; |
| 502 |
|
|
int64 nr_chunks_; |
| 503 |
|
|
std::vector<Chunk*> chunks_; |
| 504 |
|
|
std::deque<Chunk*> free_chunks_; |
| 505 |
|
|
|
| 506 |
|
|
std::unordered_map<int, std::deque<Chunk*>*> size_to_chunks_; |
| 507 |
|
|
std::unordered_map<int, Chunk*> size_to_last_used_chunk_; |
| 508 |
|
|
|
| 509 |
|
|
std::set<int> allocated_slab_sizes_; |
| 510 |
|
|
|
| 511 |
|
|
std::atomic<int64> total_malloc_ = 0; |
| 512 |
|
|
|
| 513 |
|
|
base::Lock lock_; |
| 514 |
|
|
// different slab |
| 515 |
|
|
}; |
| 516 |
|
|
|
| 517 |
|
|
// Factory wrapper for DramValueStore; matches PetKV PersistMemoryPool<false> |
| 518 |
|
|
// slabs. |
| 519 |
|
|
class PersistMemoryPoolMalloc : public PersistMemoryPool<false> { |
| 520 |
|
|
public: |
| 521 |
|
✗ |
PersistMemoryPoolMalloc(const std::string& filename, |
| 522 |
|
|
int64 memory_size, |
| 523 |
|
|
const std::string& /*medium*/) |
| 524 |
|
✗ |
: PersistMemoryPool<false>( |
| 525 |
|
|
filename, |
| 526 |
|
|
memory_size, |
| 527 |
0/4
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
✗ |
{8 + 32, 8 + 64, 8 + 128, 8 + 512, 8 + 1024}) {} |
| 528 |
|
|
}; |
| 529 |
|
|
|
| 530 |
|
|
class PersistLoopShmMalloc : public MallocApi { |
| 531 |
|
|
public: |
| 532 |
|
|
static const int max_fast_list_type = 32; |
| 533 |
|
|
static const int max_fast_list_num = 1 << 20; |
| 534 |
|
|
// filename: 文件名, 内存大小 |
| 535 |
|
|
PersistLoopShmMalloc(const std::string& filename, |
| 536 |
|
|
int64 memory_size, |
| 537 |
|
|
std::string medium = "DRAM"); |
| 538 |
|
|
// 如果分配内存不是固定的几种大小,且我们需要利用循环首次适应的 LRU 特性, |
| 539 |
|
|
// 关闭这个功能 |
| 540 |
|
|
void DisableFastMalloc() { enable_fast_malloc_ = false; } |
| 541 |
|
|
char* New(int memory_size); |
| 542 |
|
|
bool Free(void* memory_data); |
| 543 |
|
|
|
| 544 |
|
|
bool load_success() const { return load_success_; } |
| 545 |
|
|
void GetMallocsAppend(std::vector<char*>* mallocs_data) const; |
| 546 |
|
|
void GetMallocsAppend(std::vector<int64>* mallocs_offset) const; |
| 547 |
|
✗ |
std::string GetInfo() const { |
| 548 |
|
✗ |
std::string info; |
| 549 |
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
info.append(base::StringPrintf( |
| 550 |
|
|
"used/healthy/total block: %ld/%ld/%ld\n", |
| 551 |
|
✗ |
total_used_, |
| 552 |
|
✗ |
healthy_used_, |
| 553 |
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
|
✗ |
block_num_)); |
| 554 |
0/6
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
|
✗ |
info.append(total_fast_malloc_.Display() + "\n"); |
| 555 |
0/6
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
|
✗ |
info.append(total_loop_malloc_.Display() + "\n"); |
| 556 |
|
✗ |
return info; |
| 557 |
|
✗ |
} |
| 558 |
|
1082 |
void Initialize() { |
| 559 |
|
1082 |
total_used_ = 0; |
| 560 |
|
1082 |
total_malloc_ = 0; |
| 561 |
|
1082 |
last_malloc_block_ = 0; |
| 562 |
|
1082 |
memset(used_bits_, 0, block_num_ >> 3); |
| 563 |
|
1082 |
clflushopt_range(used_bits_, block_num_ >> 3); |
| 564 |
|
1082 |
} |
| 565 |
|
|
// 一共使用了多少 8 字节的 block |
| 566 |
|
7432 |
int64 total_used() const { return total_used_; } |
| 567 |
|
|
// 一共分配了多少块内存, 和 GetUsedBlockAppend 对应 |
| 568 |
|
8596 |
uint64 total_malloc() const { return total_malloc_; } |
| 569 |
|
✗ |
bool Healthy() const { return total_used_ <= healthy_used_; } |
| 570 |
|
✗ |
int64 DataBaseOffset() const { return data_ - shm_file_->Data(); } |
| 571 |
|
4 |
char* BackingData() const override { return data_; } |
| 572 |
|
12 |
int64 BackingSize() const override { return block_num_ * 8L; } |
| 573 |
|
351340 |
char* GetMallocData(int64 offset) const { |
| 574 |
3/6
✓ Branch 0 taken 351340 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 351340 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 351340 times.
|
351340 |
if (offset < 8 || (offset & 7) != 0 || offset > block_num_ * 8L) |
| 575 |
|
✗ |
return NULL; |
| 576 |
|
351340 |
return data_ + offset; |
| 577 |
|
|
} |
| 578 |
|
149550 |
int GetMallocSize(int64 offset) const { |
| 579 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 149550 times.
|
149550 |
if (offset == block_num_ * 8L) |
| 580 |
|
✗ |
return 0; |
| 581 |
3/6
✓ Branch 0 taken 149550 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 149550 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 149550 times.
|
149550 |
if (offset < 8 || (offset & 7) != 0 || offset > block_num_ * 8L) |
| 582 |
|
✗ |
return -1; |
| 583 |
|
149550 |
return Block()[BlockIndex(offset) - 1]; |
| 584 |
|
|
} |
| 585 |
|
286690 |
int64 GetMallocOffset(const char* data) const { |
| 586 |
|
286690 |
int64 offset = data - data_; |
| 587 |
3/6
✓ Branch 0 taken 286690 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 286690 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 286690 times.
|
286690 |
if (offset < 8 || (offset & 7) != 0 || offset > block_num_ * 8L) |
| 588 |
|
✗ |
return -1; |
| 589 |
|
286690 |
return offset; |
| 590 |
|
|
} |
| 591 |
|
4272 |
int GetMallocSize(const char* data) const { |
| 592 |
|
4272 |
int64 offset = GetMallocOffset(data); |
| 593 |
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4270 times.
|
4272 |
if (offset == block_num_ * 8L) |
| 594 |
|
2 |
return 0; |
| 595 |
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4270 times.
|
4270 |
if (offset < 0) |
| 596 |
|
✗ |
return -1; |
| 597 |
|
4270 |
return Block()[BlockIndex(offset) - 1]; |
| 598 |
|
|
} |
| 599 |
|
|
|
| 600 |
|
|
void AddMallocs4Recovery(int64_t shm_offset); |
| 601 |
|
|
|
| 602 |
|
|
private: |
| 603 |
|
391104 |
static int BlockNum(int memory_size) { return (memory_size + 7) >> 3; } |
| 604 |
|
263024 |
static int64 BlockIndex(int64 offset) { return offset >> 3; } |
| 605 |
|
|
bool UnusedMemoryValid(int64 block_index) const; |
| 606 |
|
|
bool MemoryValid() const; |
| 607 |
|
12478420 |
bool Used(int64 index) const { |
| 608 |
|
12478420 |
return (used_bits_[index >> 6] & (1ul << (index & 63))) != 0; |
| 609 |
|
|
} |
| 610 |
|
263792 |
const uint64* Block() const { return reinterpret_cast<const uint64*>(data_); } |
| 611 |
|
449834 |
uint64* Block() { return reinterpret_cast<uint64*>(data_); } |
| 612 |
|
|
void UseBlock(int64 index) { used_bits_[index >> 6] |= 1ul << (index & 63); } |
| 613 |
|
|
void FreeBlock(int64 index) { |
| 614 |
|
|
used_bits_[index >> 6] &= ~(1ul << (index & 63)); |
| 615 |
|
|
} |
| 616 |
|
|
std::unique_ptr<ShmFile> shm_file_; |
| 617 |
|
|
base::Lock lock_; |
| 618 |
|
|
uint64* used_bits_; |
| 619 |
|
|
char* data_; |
| 620 |
|
|
char* start_address_; |
| 621 |
|
|
int64 memory_size_; |
| 622 |
|
|
int64 block_num_; |
| 623 |
|
|
int64 last_malloc_block_; |
| 624 |
|
|
int64 total_used_; |
| 625 |
|
|
int64 total_malloc_; |
| 626 |
|
|
int64 healthy_used_; |
| 627 |
|
|
bool load_success_; |
| 628 |
|
|
bool enable_fast_malloc_ = true; |
| 629 |
|
|
StdAutoDeleteHash<std::deque<int64>> fast_malloc_lists_; |
| 630 |
|
|
Counter total_fast_malloc_{"total_fast_malloc"}; |
| 631 |
|
|
Counter total_loop_malloc_{"total_loop_malloc"}; |
| 632 |
|
|
|
| 633 |
|
|
DISALLOW_COPY_AND_ASSIGN(PersistLoopShmMalloc); |
| 634 |
|
|
}; |
| 635 |
|
|
FACTORY_REGISTER(MallocApi, |
| 636 |
|
|
PersistLoopShmMalloc, // 注册名(通常同类名) |
| 637 |
|
|
PersistLoopShmMalloc, // 具体类型 |
| 638 |
|
|
const std::string&, |
| 639 |
|
|
int64, |
| 640 |
|
|
const std::string&); |
| 641 |
|
|
FACTORY_REGISTER(MallocApi, |
| 642 |
|
|
PERSIST_LOOP_SLAB, |
| 643 |
|
|
PersistLoopShmMalloc, |
| 644 |
|
|
const std::string&, |
| 645 |
|
|
int64, |
| 646 |
|
|
const std::string&); |
| 647 |
|
|
FACTORY_REGISTER(MallocApi, |
| 648 |
|
|
PERSIST_MEMORY_POOL, |
| 649 |
|
|
PersistMemoryPoolMalloc, |
| 650 |
|
|
const std::string&, |
| 651 |
|
|
int64, |
| 652 |
|
|
const std::string&); |
| 653 |
|
|
} // namespace base |
| 654 |
|
|
|