-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCentralCache.cpp
More file actions
92 lines (92 loc) · 3.04 KB
/
CentralCache.cpp
File metadata and controls
92 lines (92 loc) · 3.04 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
//
// Created by ASUS on 2026/3/23.
//
#include "PageCache.h"
#include "CentralCache.h"
CentralCache CentralCache::_sInt;//CentralCache的饿汉对象
size_t CentralCache::FetchRangeObj(void*& start,void*& end,size_t size,size_t batchNum) {
size_t index=SizeClass::index(size);
_spanLists[index]._mtx.lock();
Span* span=GetOneSpan(_spanLists[index],size);
assert(span);
assert(span->_freelist);
start=end=span->_freelist;
size_t actualNum=1;
size_t i=0;
while (i<batchNum-1&&*reinterpret_cast<void**>(end)!=nullptr) {
end=*reinterpret_cast<void**>(end);
actualNum++;
i++;
}
span->_freelist=*reinterpret_cast<void**>(end);
span->_usecount+=actualNum;//给tc分了多少就给useCount加多少
*reinterpret_cast<void**>(end)=nullptr;
_spanLists[index]._mtx.unlock();
return actualNum;
}
Span* CentralCache::GetOneSpan(SpanList& list,size_t size) {
Span* it=list.Begin();
while (it!=list.End()) {
if (it->_freelist!=nullptr) {
return it;
}
else {
it=it->_next;
}
}
//解掉桶锁,让其他向该cc桶进行操作的线程能拿到锁
list._mtx.unlock();
size_t k=PageCache::NumMovePage(size);
PageCache::GetInstance()->_pageMtx.lock();
Span* span=PageCache::GetInstance()->newSpan(k);
span->_isUse=true;
PageCache::GetInstance()->_pageMtx.unlock();
/*
*_pageID是pageID类型(size_t或者unsigned long long)的,不能直接赋值给指针
*/
char *start=(char*)(span->_pageId<<PAGE_SHIFT);
char *end=(char*)(start+(span->_n<<PAGE_SHIFT));
//开始切分span管理空间
span->_freelist=start;
void* tail=start;
start+=size;
int i=0;
while (start<end) {
++i;
*reinterpret_cast<void**>(tail)=start;
start+=size;
tail=*reinterpret_cast<void**>(tail);
}
*reinterpret_cast<void**>(tail)=nullptr;
//切好span以后
list._mtx.lock();
list.PushFront(span);
return span;
}
void CentralCache::ReleaseListToSpans(void*start,size_t size) {
size_t index=SizeClass::index(size);
_spanLists[index]._mtx.lock();
while (start) {
void* next=*reinterpret_cast<void**>(start);
Span* span=PageCache::GetInstance()->MapObjectToSpan(start);
*reinterpret_cast<void**>(start)=span->_freelist;
span->_freelist=start;
span->_usecount--;
if (span->_usecount==0) {
_spanLists[index].Erase(span);
span->_freelist=nullptr;
span->_next=nullptr;
span->_prev=nullptr;
//归还span,解掉当前桶锁
_spanLists[index]._mtx.unlock();
//将这个span交给pc管理
PageCache::GetInstance()->_pageMtx.lock();
PageCache::GetInstance()->ReleaseSpanToPageCache(span);
PageCache::GetInstance()->_pageMtx.unlock();
//归还完毕,再加上当前桶的桶锁
_spanLists[index]._mtx.lock();
}
start=next;
}
_spanLists[index]._mtx.unlock();
}