-
Notifications
You must be signed in to change notification settings - Fork 2
/
dragon.cpp
99 lines (90 loc) · 3.92 KB
/
dragon.cpp
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
#include "dragon.hpp"
using namespace std;
bool dragon_debug = false;
CacheResultType DragonProtocol::onLoad(int pid, unsigned int address, shared_ptr<Bus> bus,
shared_ptr<Cache> cache) {
State state = cache->getCacheLineState(address);
// handle counters
if (state == M || state == E) {
numPrivate++;
} else if (state == Sm || state == Sc) {
numShared++;
}
// actual processing
if (state == M || state == E || state == Sm) {
if (dragon_debug) cout << "M/E/Sm: load hit" << endl;
cache->updateCacheLine(address, state);
return CACHEHIT;
} else if (state == Sc) {// ensure coherency
// check if it is store in the dictionary, if is stored it will be stalled.
size_t indexWithTag = cache->getIndexWithTag(address);
bool isCacheBlocked = bus->checkCacheBlocked(indexWithTag, pid);
if (dragon_debug)
cout << "cache is blocked for processor " << pid << "isblocked: " << isCacheBlocked
<< endl;
if (!isCacheBlocked) {
if (dragon_debug) cout << "Sc: load hit" << endl;
cache->updateCacheLine(address, state);
return CACHEHIT;
}
if (dragon_debug) cout << "Sc: load blocked" << endl;
return CACHEBLOCKED;
} else if (state == I) {
if (dragon_debug) cout << "I: load miss" << endl;
shared_ptr<Request> busRdRequest = make_shared<Request>(pid, BusRd, address);
bus->pushRequestToBus(busRdRequest);
return CACHEMISS;
} else {
throw runtime_error("invalid state");
}
}
CacheResultType DragonProtocol::onStore(int pid, unsigned int address, shared_ptr<Bus> bus,
shared_ptr<Cache> cache) {
State state = cache->getCacheLineState(address);
if (state == M) {
if (dragon_debug) cout << "M: store hit" << endl;
numPrivate++;
cache->updateCacheLine(address, state);
return CACHEHIT;
} else if (state == Sm) {
if (dragon_debug) cout << "Sm: store hit" << endl;
size_t indexWithTag = cache->getIndexWithTag(address);
bus->addCacheBlocked(indexWithTag, pid); // block the cache from other modifications
shared_ptr<Request> busRdRequest = make_shared<Request>(-2, BusUpd, address);
cache->updateCacheLine(address, state);
bus->pushRequestToBus(busRdRequest);
numShared++;
return CACHEHIT;
} else if (state == E) {
// change state to M
if (dragon_debug) cout << "E: store hit" << endl;
cache->updateCacheLine(address, M);
numPrivate++;
return CACHEHIT;
} else if (state == Sc) {
// check if it is store in the dictionary, if is stored it will be stalled.
size_t indexWithTag = cache->getIndexWithTag(address);
bool isCacheBlocked = bus->checkCacheBlocked(indexWithTag, pid);
if (!isCacheBlocked) {
if (dragon_debug) cout << "Sc: store hit" << endl;
cache->updateCacheLine(address, Sm);
bus->updateOtherCachesToSc(address, pid);
bus->addCacheBlocked(indexWithTag, pid); // block the cache from other modifications
shared_ptr<Request> busRdRequest = make_shared<Request>(-2, BusUpd, address);
bus->pushRequestToBus(busRdRequest);
numShared++;
return CACHEHIT;
}
return CACHEBLOCKED;
} else if (state == I) {
// will also need to check whether other processors have the cache
if (dragon_debug) cout << "I: store miss" << endl;
shared_ptr<Request> busRdRequest = make_shared<Request>(pid, BusUpd, address);
bus->pushRequestToBus(busRdRequest);
return CACHEMISS;
} else {
throw runtime_error("invalid state");
}
}
unsigned int DragonProtocol::getNumShared() { return numShared; }
unsigned int DragonProtocol::getNumPrivate() { return numPrivate; }