-
Notifications
You must be signed in to change notification settings - Fork 0
/
TheadCache.cpp
67 lines (57 loc) · 1.62 KB
/
TheadCache.cpp
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
56
57
58
59
60
61
62
63
64
65
66
67
#include "ThreadCache.h"
#include "CentralCache.h"
void* ThreadCache::FetchFromCentralCache(size_t i, size_t size)
{
// 获取一批对象,数量使用慢启动方式
// SizeClass::NumMoveSize(size)是上限值
size_t batchNum = min(SizeClass::NumMoveSize(size), _freeLists[i].MaxSize());
// 去中心缓存获取batch_num个对象
void* start = nullptr;
void* end = nullptr;
size_t actualNum = CentralCache::GetInstance()->FetchRangeObj(start, end, batchNum, SizeClass::RoundUp(size));
assert(actualNum > 0);
// >1,返回一个,剩下挂到自由链表
// 如果一次申请多个,剩下挂起来,下次申请就不需要找中心缓存
// 减少锁竞争,提高效率
if (actualNum > 1)
{
_freeLists[i].PushRange(NextObj(start), end, actualNum - 1);
}
// 慢启动增长
if (_freeLists[i].MaxSize() == batchNum)
{
_freeLists[i].SetMaxSize(_freeLists[i].MaxSize() + 1);
}
return start;
}
void* ThreadCache::Allocate(size_t size) // 通过映射规则去算,属于哪一号桶
{
size_t i = SizeClass::Index(size);
if (!_freeLists[i].Empty())
{
return _freeLists[i].Pop(); // 把这个内存块的地址给返回出去
}
else
{
return FetchFromCentralCache(i, size);
}
}
void ThreadCache::Deallocate(void* ptr, size_t size)
{
size_t i = SizeClass::Index(size);
_freeLists[i].Push(ptr);
// List Too Long central cache 去释放
if (_freeLists[i].Size() >= _freeLists[i].MaxSize())
{
ListTooLong(_freeLists[i], size);
}
}
// 释放对象时,链表过长时,回收内存回到中心缓存
void ThreadCache::ListTooLong(FreeList& list, size_t size)
{
size_t batchNum = list.MaxSize();
void* start = nullptr;
void* end = nullptr;
list.PopRange(start, end, batchNum);
CentralCache::GetInstance()->ReleaseListToSpans(start, size);
}