-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathThreadCache.h
More file actions
151 lines (146 loc) · 4.39 KB
/
ThreadCache.h
File metadata and controls
151 lines (146 loc) · 4.39 KB
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//
// Created by ASUS on 2026/3/21.
//
#ifndef MEMORY_POOL_IMPROVEMENT_THREADCACHE_H
#define MEMORY_POOL_IMPROVEMENT_THREADCACHE_H
#include <cassert>
#include <cstddef>
#include <iostream>
#include <thread>
#define FREE_LIST_SIZE 208//桶个数
#define MAX_BYTE 256*1024//ThreadThreadCache单次申请的最大字节数8k
#define PAGE_NUM 129//span的最大管理页数
#define PAGE_SHIFT 13
#define NOMINMAX
#include <Windows.h>
class Freelist {
//直接操作内存地址
public:
void PopRange(void*& start,void*& end,size_t n) {
assert(n<=_size);
start=end=freelist_;
for (size_t i=0;i<n-1;i++) {
end=*reinterpret_cast<void**>(end);
}
freelist_=*reinterpret_cast<void**>(end);
*reinterpret_cast<void**>(end)=nullptr;
_size-=n;
}
void PushRange(void*start,void*end,size_t size) {
*reinterpret_cast<void**>(end)=freelist_;
freelist_=start;
_size+=size;
}
bool empty() {
return freelist_==nullptr;
}
//push在里面充当删除的功能,将内存块传入空闲链表表示删除不需要有返回值,pop在里面充当获取的功能,返回一个内存块(void*)
void* pop() {
if (freelist_ == nullptr) {
return nullptr;
}
void* ptr=freelist_;
freelist_=*reinterpret_cast<void**>(freelist_);
--_size;
return ptr;
}
void push(void*ptr) {
if (ptr == nullptr) {
return;
}
*reinterpret_cast<void**>(ptr)=freelist_;
freelist_=ptr;
++_size;
}
size_t& MaxSize() {
return _maxSize;
}
size_t Size() {
return _size;
}
private:
void* freelist_=nullptr;
size_t _maxSize=1;
size_t _size=0;//表示当前自由链表还有多少块空间
};
class ThreadCache {
public:
void* allocate(size_t size);
void deallocate(void* ptr, size_t size);
//ThreadCache中空间不够时,向CentralCache中获取
void* FetchFromCentralCache(size_t index,size_t alignSize);
void ListTooLong(Freelist& list,size_t size);
private:
Freelist freelist_[FREE_LIST_SIZE];
};
//tls的全局对象指针,这样每个线程都能拥有一个独立的全局对象
extern thread_local ThreadCache* pTLSThreadCache;
class SizeClass {
public:
static size_t _Roundup(size_t size,size_t align) {
if (size % align == 0) {
return size;
}
else {
return (size/align+1)*align;
}
}
static size_t Roundup(size_t size) {
if (size <= 128) return _Roundup(size, 8);
else if (size <= 1024) return _Roundup(size, 16);
else if (size <= 8 * 1024) return _Roundup(size, 128);
else if (size <= 64 * 1024) return _Roundup(size, 1024);
else if (size <= 256 * 1024) return _Roundup(size, 8192);
else return size;
}
//返回链表中桶位置
static inline size_t _index(size_t size,size_t align_shift) {
return ((size+(1<<align_shift)-1)>>align_shift)-1;//先向上取整然后-1得到下标
}
//返回总的位置
static inline size_t index(size_t size) {
assert(size<MAX_BYTE);
static int group_array[4] = {16, 56, 56, 56};
if (size <= 128) {
return _index(size, 3);
} else if (size <= 1024) {
return _index(size-128,4)+group_array[0];
}
else if (size<=1024*8) {
return _index(size-1024,7)+group_array[1]+group_array[0];
}
else if (size<=1024*64) {
return _index(size-1024*8,10)+group_array[2]+group_array[1]+group_array[0];
}
else if (size<=1024*256) {
return _index(size-1024*64,13)+group_array[3]+group_array[2]+group_array[1]+group_array[0];
}
else {
assert(false);
}
return -1;
}
static size_t NumMoveSize(size_t size) {
//申请的块数,太多了就512,少了就给两块
assert(size>0);
int num=MAX_BYTE/size;
if (num>512) {
num=512;
}
if (num<2) {
num=2;
}
return num;
}
};
inline static void* SystemAlloc(size_t kpage) {
#ifdef _WIN32
void* ptr=VirtualAlloc(nullptr,kpage<<PAGE_SHIFT,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
#else
#endif
if (ptr==nullptr) {
throw std::bad_alloc();
}
return ptr;
}
#endif //MEMORY_POOL_IMPROVEMENT_THREADCACHE_H