Skip to content

Commit 0aa5493

Browse files
authored
Merge pull request #2 from Icingworld/dev
Detect and fix some bugs
2 parents 611e769 + 12731a0 commit 0aa5493

File tree

11 files changed

+77
-56
lines changed

11 files changed

+77
-56
lines changed

memory-pool/include/CentralCache.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,11 @@
55
namespace WW
66
{
77

8-
constexpr std::size_t MAX_ARRAY_SIZE = 208; // 内存大小数组最大大小
9-
108
/**
119
* @brief 中心缓存
1210
*/
1311
class CentralCache
1412
{
15-
public:
16-
using size_type = std::size_t;
17-
1813
private:
1914
PageCache & _Page_cache; // 页缓存
2015
std::array<SpanList, MAX_ARRAY_SIZE> _Spans; // 页段链表数组

memory-pool/include/Common.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#pragma once
2+
3+
#include <cstddef>
4+
5+
namespace WW
6+
{
7+
8+
using size_type = std::size_t; // 大小类型定义
9+
10+
constexpr size_type PAGE_SIZE = 4096; // 单页大小
11+
constexpr size_type PAGE_SHIFT = 12; // 页号计算移位数
12+
13+
constexpr size_type MAX_PAGE_NUM = 128; // 最大页数
14+
15+
constexpr size_type MAX_ARRAY_SIZE = 208; // 内存块数组大小
16+
17+
constexpr size_type MAX_MEMORY_SIZE = PAGE_SIZE * MAX_PAGE_NUM / 2; // 内存池可以管理的最大内存
18+
19+
} // namespace WW

memory-pool/include/FreeList.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#pragma once
22

3-
#include <cstddef>
3+
#include <Common.h>
44

55
namespace WW
66
{
@@ -85,7 +85,7 @@ class FreeListIterator
8585
class FreeList
8686
{
8787
public:
88-
using size_type = std::size_t; // 内存块数量范围为0-65535,使用uint16_t存储
88+
using size_type = std::size_t;
8989
using iterator = FreeListIterator;
9090

9191
private:

memory-pool/include/PageCache.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,13 @@
88
namespace WW
99
{
1010

11-
constexpr std::uint8_t MAX_PAGE_COUNT = 128; // 最大页数
12-
1311
/**
1412
* @brief 页缓存
1513
*/
1614
class PageCache
1715
{
18-
public:
19-
using size_type = std::size_t;
20-
2116
private:
22-
std::array<SpanList, MAX_PAGE_COUNT> _Spans; // 页段链表数组
17+
std::array<SpanList, MAX_PAGE_NUM> _Spans; // 页段链表数组
2318
std::unordered_map<size_type, Span *> _Span_map; // 页号到页段指针的映射
2419
std::recursive_mutex _Mutex; // 页缓存锁
2520

memory-pool/include/SpanList.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,15 @@
77
namespace WW
88
{
99

10-
constexpr std::size_t PAGE_SIZE = 4096; // 单页大小
11-
constexpr std::size_t PAGE_SHIFT = 12; // 页号计算移位数
12-
1310
/**
1411
* @brief 页段
1512
* @details 维护一大段连续的内存
1613
*/
1714
class Span
1815
{
19-
public:
20-
using size_type = std::size_t;
21-
2216
private:
2317
FreeList _Free_list; // 空闲内存块
24-
size_type _Page_id; // 页段号
18+
size_type _Page_id; // 页段号
2519
Span * _Prev; // 前一个页段
2620
Span * _Next; // 后一个页段
2721
size_type _Page_count; // 页数

memory-pool/include/ThreadCache.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,11 @@
55
namespace WW
66
{
77

8-
constexpr std::size_t MAX_MEMORY_SIZE = PAGE_SIZE * MAX_PAGE_COUNT; // 内存池可以管理的最大内存
9-
108
/**
119
* @brief 线程缓存
1210
*/
1311
class ThreadCache
1412
{
15-
public:
16-
using size_type = std::size_t;
17-
1813
private:
1914
CentralCache & _Central_cache; // 中心缓存
2015
std::array<FreeList, MAX_ARRAY_SIZE> _Freelists; // 自由表数组

memory-pool/src/CentralCache.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ void CentralCache::returnRange(size_type size, FreeObject * free_object)
8282
}
8383
}
8484

85-
CentralCache::size_type CentralCache::sizeToIndex(size_type size) noexcept
85+
size_type CentralCache::sizeToIndex(size_type size) noexcept
8686
{
8787
if (size <= 128) {
8888
return (size + 8 - 1) / 8 - 1;
@@ -123,12 +123,12 @@ Span * CentralCache::getFreeSpan(size_type size)
123123
// 初步计算需要多少页
124124
std::size_t page_count = total_size / PAGE_SIZE;
125125
// 如果还有剩余内存,则需要申请额外的一页
126-
if (total_size % MAX_PAGE_COUNT != 0) {
126+
if (total_size % MAX_PAGE_NUM != 0) {
127127
page_count += 1;
128128
}
129129
// 每个页段最多只有128页
130-
if (page_count > MAX_PAGE_COUNT) {
131-
page_count = MAX_PAGE_COUNT;
130+
if (page_count > MAX_PAGE_NUM) {
131+
page_count = MAX_PAGE_NUM;
132132
}
133133

134134
// 申请页段

memory-pool/src/FreeList.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ bool FreeList::empty() const noexcept
105105
return (_Head->next() == nullptr);
106106
}
107107

108-
FreeList::size_type FreeList::size() const noexcept
108+
size_type FreeList::size() const noexcept
109109
{
110110
return _Size;
111111
}

memory-pool/src/PageCahce.cpp renamed to memory-pool/src/PageCache.cpp

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "PageCache.h"
22

3+
#include <cstdlib>
4+
35
namespace WW
46
{
57

@@ -12,7 +14,20 @@ PageCache::PageCache()
1214

1315
PageCache::~PageCache()
1416
{
15-
// TODO
17+
// 释放所有页段
18+
for (size_type i = 0; i < MAX_PAGE_NUM; ++i) {
19+
while (!_Spans[i].empty()) {
20+
Span & span = _Spans[i].front();
21+
_Spans[i].pop_front();
22+
23+
// 释放页段管理的内存空间
24+
void * ptr = Span::idToPtr(span.id());
25+
free(ptr);
26+
27+
// 销毁页段
28+
delete(&span);
29+
}
30+
}
1631
}
1732

1833
PageCache & PageCache::getPageCache()
@@ -33,7 +48,7 @@ Span * PageCache::fetchSpan(size_type count)
3348
}
3449

3550
// 没有正好这么大的页段,尝试从更大块内存中切出页段
36-
for (size_type i = count; i < MAX_PAGE_COUNT; ++i) {
51+
for (size_type i = count; i < MAX_PAGE_NUM; ++i) {
3752
if (!_Spans[i].empty()) {
3853
// 取出页段
3954
Span & bigger_span = _Spans[i].front();
@@ -67,16 +82,16 @@ Span * PageCache::fetchSpan(size_type count)
6782

6883
// 没找到更大的页段,直接申请一个最大的页段,然后按照上面的流程重新获取页段
6984
Span * max_span = new Span();
70-
void * ptr = fetchFromSystem(MAX_PAGE_COUNT);
85+
void * ptr = fetchFromSystem(MAX_PAGE_NUM);
7186
if (ptr == nullptr) {
7287
return nullptr;
7388
}
7489

7590
// 计算页号
7691
max_span->setId(Span::ptrToId(ptr));
77-
max_span->setCount(MAX_PAGE_COUNT);
78-
// 插入MAX_PAGE_COUNT页的链表中
79-
_Spans[MAX_PAGE_COUNT - 1].push_front(max_span);
92+
max_span->setCount(MAX_PAGE_NUM);
93+
// 插入MAX_PAGE_NUM页的链表中
94+
_Spans[MAX_PAGE_NUM - 1].push_front(max_span);
8095
// 首页号插入哈希表
8196
_Span_map[max_span->id()] = max_span;
8297
// 尾页号插入哈希表
@@ -103,23 +118,25 @@ void PageCache::returnSpan(Span * span)
103118
break;
104119
}
105120

121+
Span * span_prev = it->second;
122+
106123
// 判断合并后是否超出上限
107-
if (span->count() + it->second->count() > MAX_PAGE_COUNT) {
124+
if (span->count() + span_prev->count() > MAX_PAGE_NUM) {
108125
break;
109126
}
110127

111128
// 从链表中删除该空闲页
112-
_Spans[it->second->count() - 1].erase(it->second);
129+
_Spans[span_prev->count() - 1].erase(span_prev);
113130
// 从哈希表中删除该空闲页的首尾页号
114-
_Span_map.erase(it->second->id());
115-
_Span_map.erase(it->second->id() + it->second->count() - 1);
131+
_Span_map.erase(span_prev->id());
132+
_Span_map.erase(span_prev->id() + span_prev->count() - 1);
116133

117134
// 合并页段
118-
span->setId(it->second->id());
119-
span->setCount(it->second->count() + span->count());
135+
span->setId(span_prev->id());
136+
span->setCount(span_prev->count() + span->count());
120137

121138
// 删除原空闲页
122-
delete it->second;
139+
delete span_prev;
123140
}
124141

125142
// 向后寻找空闲的页
@@ -133,21 +150,23 @@ void PageCache::returnSpan(Span * span)
133150
}
134151

135152
// 判断合并后是否超出上限
136-
if (span->count() + it->second->count() > MAX_PAGE_COUNT) {
153+
if (span->count() + it->second->count() > MAX_PAGE_NUM) {
137154
break;
138155
}
139156

157+
Span * span_next = it->second;
158+
140159
// 从链表中删除该空闲页
141-
_Spans[it->second->count() - 1].erase(it->second);
160+
_Spans[span_next->count() - 1].erase(span_next);
142161
// 从哈希表中删除该空闲页的首尾页号
143-
_Span_map.erase(it->second->id());
144-
_Span_map.erase(it->second->id() + it->second->count() - 1);
162+
_Span_map.erase(span_next->id());
163+
_Span_map.erase(span_next->id() + span_next->count() - 1);
145164

146165
// 合并页段,首页号不变,只需要调整大小
147-
span->setCount(it->second->count() + span->count());
166+
span->setCount(span_next->count() + span->count());
148167

149168
// 删除原空闲页
150-
delete it->second;
169+
delete span_next;
151170
}
152171

153172
// 合并完成,插入新的链表
@@ -173,7 +192,11 @@ Span * PageCache::FreeObjectToSpan(void * ptr)
173192

174193
void * PageCache::fetchFromSystem(size_type count) const noexcept
175194
{
176-
return ::operator new(count * PAGE_SIZE, std::nothrow);
195+
void * ptr = nullptr;
196+
if (posix_memalign(&ptr, PAGE_SIZE, count * PAGE_SIZE) != 0) {
197+
return nullptr;
198+
}
199+
return ptr;
177200
}
178201

179202
} // namespace WW

memory-pool/src/SpanList.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Span::Span()
1313
{
1414
}
1515

16-
Span::size_type Span::id() const noexcept
16+
size_type Span::id() const noexcept
1717
{
1818
return _Page_id;
1919
}
@@ -23,7 +23,7 @@ void Span::setId(size_type page_id) noexcept
2323
_Page_id = page_id;
2424
}
2525

26-
Span::size_type Span::count() const noexcept
26+
size_type Span::count() const noexcept
2727
{
2828
return _Page_count;
2929
}
@@ -53,7 +53,7 @@ void Span::setNext(Span * next) noexcept
5353
_Next = next;
5454
}
5555

56-
Span::size_type Span::used() const noexcept
56+
size_type Span::used() const noexcept
5757
{
5858
return _Used;
5959
}
@@ -68,7 +68,7 @@ FreeList * Span::getFreeList() noexcept
6868
return &_Free_list;
6969
}
7070

71-
Span::size_type Span::ptrToId(void * ptr) noexcept
71+
size_type Span::ptrToId(void * ptr) noexcept
7272
{
7373
return reinterpret_cast<std::uintptr_t>(ptr) >> PAGE_SHIFT;
7474
}

0 commit comments

Comments
 (0)