-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmob.cpp
More file actions
228 lines (186 loc) · 5.1 KB
/
Copy pathmob.cpp
File metadata and controls
228 lines (186 loc) · 5.1 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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
/* _ooOoo_
o8888888o
88" . "88
(| -_- |)
O\ = /O
____/`---'\____
. ' \\| |// `.
/ \\||| : |||// \
/ _||||| -:- |||||- \
| | \\\ - /// | |
| \_| ''\---/'' | |
\ .-\__ `-` ___/-. /
___`. .' /--.--\ `. . __
."" '< `.___\_<|>_/___.' >'"".
| | : `- \`.;`\ _ /`;.`/ - ` : | |
\ \ `-. \_ __\ /__ _/ .-` / /
======`-.____`-.___\_____/___.-`____.-'======
`=---='
.............................................
佛祖保佑 永无BUG
佛曰:
写字楼里写字间,写字间里程序员;
程序人员写程序,又拿程序换酒钱。
酒醒只在网上坐,酒醉还来网下眠;
酒醉酒醒日复日,网上网下年复年。
但愿老死电脑间,不愿鞠躬老板前;
奔驰宝马贵者趣,公交自行程序员。
别人笑我忒疯癫,我笑自己命太贱;
不见满街漂亮妹,哪个归得程序员?
*/
/**
* mob.cpp
*
* Copyright (C) 2024 SCTY
*
* Description:
*
* Revision History:
*
* 2025-01-13 Created By YangLing (yl.tienon@gmail.com)
*/
#if defined(HAVE_STORE_BUFFER)
#include <mutex>
#include <condition_variable>
#include <deque>
#include <map>
#include "basic_type.hpp"
#include "bsb.hpp"
#include "store_buffer.hpp"
#include "mob.hpp"
#include "system.hpp"
mob::mob(bsb * b, const std::size_t m) : max(m)
{
bus = b;
}
void mob::PrRd(const pr_data_opt_t & addr, pr_data_val_t & data)
{
{
// Store Buffer Forwarding
std::unique_lock lck(cs);
if (const auto & s = dat_map.find(addr); s != dat_map.end())
{
data = s->second->get_data();
return;
}
bus->PrRd(addr, data);
}
}
void mob::PrWr(const pr_data_opt_t & addr, const pr_data_val_t & data)
{
{
std::unique_lock lck(cs);
// Store Buffer Forwarding
if (const auto & s = dat_map.find(addr); s != dat_map.end())
{
s->second->set_data(data);
return;
}
/*
*
* +-----------> Store Buffer
* | /|\
* Yes |
* | |
* ---> 存在写栅栏---+ +-----+
* | |
* No Write Miss
* | |
* +--- PrWr---+
* |
* Write Hit
* |
* +-------- 结束
*
*/
// 如果没有写栅栏,尝试直接写 cache, 如果 cache hit.就直接返回了
if (wmb_map.empty() && bus->PrWr_async(addr, data))
return;
// Store Buffer 最多只能有 max 个, 超过只能等待
while (dat_que.size() >= max)
{
cv_pr.wait(lck);
}
// 经过了 cv 条件等待, 那么是有可能存在竞争条件的.必须检查程序逻辑错误
if (const auto & s = dat_map.find(addr); s != dat_map.end())
// 不可能发生,一定有逻辑问题
system::oops(__FILE__, __LINE__);
store_buffer * sbp = new store_buffer(addr, data);
dat_map[addr] = sbp;
dat_que.push_back(sbp);
}
cv_sb.notify_one();
}
void mob::PrWMB(void)
{
{
std::unique_lock lck(cs);
if (dat_que.size())
{
store_buffer * sbp = dat_que.back();
sbp->set_flag();
if (const auto & s = wmb_map.find(sbp->get_addr()); s == wmb_map.end())
wmb_map[sbp->get_addr()] = sbp;
}
}
}
void mob::PrMB(void)
{
{
std::unique_lock lck(cs);
while (dat_que.size() != 0)
{
cv_pr.wait(lck);
}
}
}
void mob::PrSBF(void)
{
{
std::unique_lock lck(cs);
while (dat_que.size() != 0)
{
cv_pr.wait(lck);
}
}
}
void mob::process(void)
{
{
std::unique_lock lck(cs);
while (dat_que.size() == 0)
{
cv_sb.wait(lck);
}
}
// 故意离开一下锁,更好的制造出来 WMB 的效果
{
bool notify = false;
std::unique_lock lck(cs);
if (dat_que.size() >= max || dat_que.size() == 1)
notify = true; // 可能有人因为 Store Buffer 满了而等待/或者因为清空 SB 而等待
if (dat_que.empty())
system::oops(__FILE__, __LINE__);
store_buffer * sbp = dat_que.front();
bus->PrWr(sbp->get_addr(), sbp->get_data());
dat_que.pop_front();
if (const auto & s = dat_map.find(sbp->get_addr()); s == dat_map.end())
system::oops(__FILE__, __LINE__);
else
dat_map.erase(sbp->get_addr());
if (const auto & s = wmb_map.find(sbp->get_addr()); s != wmb_map.end())
wmb_map.erase(sbp->get_addr());
lck.unlock();
if (notify)
cv_pr.notify_one();
delete sbp;
}
}
void mob::mob_thread(mob * obj)
{
while (true)
{
obj->process();
}
}
#endif // HAVE_STORE_BUFFER