-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathaddr_trans_table.cc
70 lines (60 loc) · 1.91 KB
/
addr_trans_table.cc
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
// addr_trans_table.cc
// Copyright (c) 2014 Jinglei Ren <jinglei@ren.systems>
#include "addr_trans_table.h"
using namespace std;
const char* ATTEntry::state_strings[] = {
"CLEAN", "LOAN", "FREE", "DIRTY", "HIDDEN", "TEMP", "STAINED"
};
int AddrTransTable::Lookup(Tag phy_tag, Profiler& pf) {
pf.AddTableOp();
unordered_map<Tag, int>::iterator it = tag_index_.find(phy_tag);
if (it == tag_index_.end()) { // not hit
return -EINVAL;
} else {
ATTEntry& entry = entries_[it->second];
assert(entry.state != ATTEntry::FREE && entry.phy_tag == phy_tag);
// LRU
GetQueue(entry.state).Remove(it->second);
GetQueue(entry.state).PushBack(it->second);
return it->second;
}
}
int AddrTransTable::Setup(Tag phy_tag, Addr mach_base, ATTEntry::State state,
Profiler& pf) {
assert(tag_index_.count(phy_tag) == 0);
assert(!GetQueue(ATTEntry::FREE).Empty());
int i = GetQueue(ATTEntry::FREE).PopFront();
GetQueue(state).PushBack(i);
entries_[i].state = state;
entries_[i].phy_tag = phy_tag;
entries_[i].mach_base = mach_base;
tag_index_[phy_tag] = i;
pf.AddTableOp();
return i;
}
void AddrTransTable::ShiftState(int index, ATTEntry::State new_state,
Profiler& pf) {
ATTEntry& entry = entries_[index];
assert(entry.state != new_state);
if (new_state == ATTEntry::FREE) {
tag_index_.erase(entry.phy_tag);
}
GetQueue(entry.state).Remove(index);
GetQueue(new_state).PushBack(index);
entries_[index].state = new_state;
pf.AddTableOp();
}
void AddrTransTable::Reset(int index,
Addr new_base, ATTEntry::State new_state, Profiler& pf) {
ATTEntry& entry = entries_[index];
entry.mach_base = new_base;
ShiftState(index, new_state, pf);
}
void AddrTransTable::ClearStats(Profiler& pf) {
for (vector<ATTEntry>::iterator it = entries_.begin(); it != entries_.end();
++it) {
it->epoch_reads = 0;
it->epoch_writes = 0;
}
pf.AddTableOp(); // assumed in parallel
}