blob: 4addca2fe65b11ed75c4998f51f7e067214c93ec (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
#include "pool.h"
TMemoryPool::IGrowPolicy* TMemoryPool::TLinearGrow::Instance() noexcept {
return SingletonWithPriority<TLinearGrow, 0>();
}
TMemoryPool::IGrowPolicy* TMemoryPool::TExpGrow::Instance() noexcept {
return SingletonWithPriority<TExpGrow, 0>();
}
void TMemoryPool::AddChunk(size_t hint) {
const size_t dataLen = Max(BlockSize_, hint);
size_t allocSize = dataLen + sizeof(TChunk);
if (Options_.RoundUpToNextPowerOfTwo) {
allocSize = FastClp2(allocSize);
}
TBlock nb = Alloc_->Allocate(allocSize);
// Add previous chunk's stats
if (Current_ != &Empty_) {
MemoryAllocatedBeforeCurrent_ += Current_->Used();
MemoryWasteBeforeCurrent_ += Current_->Left();
}
BlockSize_ = GrowPolicy_->Next(dataLen);
Current_ = new (nb.Data) TChunk(nb.Len - sizeof(TChunk));
Chunks_.PushBack(Current_);
}
void TMemoryPool::DoClear(bool keepfirst) noexcept {
while (!Chunks_.Empty()) {
TChunk* c = Chunks_.PopBack();
if (keepfirst && Chunks_.Empty()) {
c->ResetChunk();
Chunks_.PushBack(c);
Current_ = c;
BlockSize_ = c->BlockLength() - sizeof(TChunk);
MemoryAllocatedBeforeCurrent_ = 0;
MemoryWasteBeforeCurrent_ = 0;
return;
}
TBlock b = {c, c->BlockLength()};
c->~TChunk();
Alloc_->Release(b);
}
Current_ = &Empty_;
BlockSize_ = Origin_;
MemoryAllocatedBeforeCurrent_ = 0;
MemoryWasteBeforeCurrent_ = 0;
}
|