Better handling of deferred targets.
--HG-- extra : convert_revision : 0fbc28c32c1eeb3dd672df14c1d53bd516f81d0f
This commit is contained in:
parent
245b0bd9b9
commit
47bce8ef78
6 changed files with 144 additions and 104 deletions
3
src/mem/cache/base_cache.cc
vendored
3
src/mem/cache/base_cache.cc
vendored
|
@ -42,8 +42,7 @@ using namespace std;
|
||||||
|
|
||||||
BaseCache::CachePort::CachePort(const std::string &_name, BaseCache *_cache)
|
BaseCache::CachePort::CachePort(const std::string &_name, BaseCache *_cache)
|
||||||
: SimpleTimingPort(_name, _cache), cache(_cache), otherPort(NULL),
|
: SimpleTimingPort(_name, _cache), cache(_cache), otherPort(NULL),
|
||||||
blocked(false), waitingOnRetry(false), mustSendRetry(false),
|
blocked(false), mustSendRetry(false), requestCauses(0)
|
||||||
requestCauses(0)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
src/mem/cache/base_cache.hh
vendored
2
src/mem/cache/base_cache.hh
vendored
|
@ -118,8 +118,6 @@ class BaseCache : public MemObject
|
||||||
|
|
||||||
bool blocked;
|
bool blocked;
|
||||||
|
|
||||||
bool waitingOnRetry;
|
|
||||||
|
|
||||||
bool mustSendRetry;
|
bool mustSendRetry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
3
src/mem/cache/cache.hh
vendored
3
src/mem/cache/cache.hh
vendored
|
@ -182,8 +182,7 @@ class Cache : public BaseCache
|
||||||
BlkType *handleFill(PacketPtr pkt, BlkType *blk,
|
BlkType *handleFill(PacketPtr pkt, BlkType *blk,
|
||||||
PacketList &writebacks);
|
PacketList &writebacks);
|
||||||
|
|
||||||
bool satisfyCpuSideRequest(PacketPtr pkt, BlkType *blk);
|
void satisfyCpuSideRequest(PacketPtr pkt, BlkType *blk);
|
||||||
bool satisfyTarget(MSHR::Target *target, BlkType *blk);
|
|
||||||
bool satisfyMSHR(MSHR *mshr, PacketPtr pkt, BlkType *blk);
|
bool satisfyMSHR(MSHR *mshr, PacketPtr pkt, BlkType *blk);
|
||||||
|
|
||||||
void doTimingSupplyResponse(PacketPtr req_pkt, uint8_t *blk_data);
|
void doTimingSupplyResponse(PacketPtr req_pkt, uint8_t *blk_data);
|
||||||
|
|
129
src/mem/cache/cache_impl.hh
vendored
129
src/mem/cache/cache_impl.hh
vendored
|
@ -368,7 +368,7 @@ Cache<TagStore,Coherence>::timingAccess(PacketPtr pkt)
|
||||||
if (mshr->threadNum != 0/*pkt->req->getThreadNum()*/) {
|
if (mshr->threadNum != 0/*pkt->req->getThreadNum()*/) {
|
||||||
mshr->threadNum = -1;
|
mshr->threadNum = -1;
|
||||||
}
|
}
|
||||||
mshr->allocateTarget(pkt, true);
|
mshr->allocateTarget(pkt);
|
||||||
if (mshr->getNumTargets() == numTarget) {
|
if (mshr->getNumTargets() == numTarget) {
|
||||||
noTargetMSHR = mshr;
|
noTargetMSHR = mshr;
|
||||||
setBlocked(Blocked_NoTargets);
|
setBlocked(Blocked_NoTargets);
|
||||||
|
@ -483,8 +483,7 @@ Cache<TagStore,Coherence>::atomicAccess(PacketPtr pkt)
|
||||||
if (isCacheFill) {
|
if (isCacheFill) {
|
||||||
PacketList writebacks;
|
PacketList writebacks;
|
||||||
blk = handleFill(busPkt, blk, writebacks);
|
blk = handleFill(busPkt, blk, writebacks);
|
||||||
bool status = satisfyCpuSideRequest(pkt, blk);
|
satisfyCpuSideRequest(pkt, blk);
|
||||||
assert(status);
|
|
||||||
delete busPkt;
|
delete busPkt;
|
||||||
|
|
||||||
// Handle writebacks if needed
|
// Handle writebacks if needed
|
||||||
|
@ -538,12 +537,14 @@ Cache<TagStore,Coherence>::functionalAccess(PacketPtr pkt,
|
||||||
|
|
||||||
// There can be many matching outstanding writes.
|
// There can be many matching outstanding writes.
|
||||||
std::vector<MSHR*> writes;
|
std::vector<MSHR*> writes;
|
||||||
writeBuffer.findMatches(blk_addr, writes);
|
assert(!writeBuffer.findMatches(blk_addr, writes));
|
||||||
|
/* Need to change this to iterate through targets in mshr??
|
||||||
for (int i = 0; i < writes.size(); ++i) {
|
for (int i = 0; i < writes.size(); ++i) {
|
||||||
MSHR *mshr = writes[i];
|
MSHR *mshr = writes[i];
|
||||||
if (pkt->checkFunctional(mshr->addr, mshr->size, mshr->writeData))
|
if (pkt->checkFunctional(mshr->addr, mshr->size, mshr->writeData))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
otherSidePort->checkAndSendFunctional(pkt);
|
otherSidePort->checkAndSendFunctional(pkt);
|
||||||
}
|
}
|
||||||
|
@ -557,43 +558,30 @@ Cache<TagStore,Coherence>::functionalAccess(PacketPtr pkt,
|
||||||
|
|
||||||
|
|
||||||
template<class TagStore, class Coherence>
|
template<class TagStore, class Coherence>
|
||||||
bool
|
void
|
||||||
Cache<TagStore,Coherence>::satisfyCpuSideRequest(PacketPtr pkt, BlkType *blk)
|
Cache<TagStore,Coherence>::satisfyCpuSideRequest(PacketPtr pkt, BlkType *blk)
|
||||||
{
|
{
|
||||||
if (blk && (pkt->needsExclusive() ? blk->isWritable() : blk->isValid())) {
|
assert(blk);
|
||||||
assert(pkt->isWrite() || pkt->isReadWrite() || pkt->isRead());
|
assert(pkt->needsExclusive() ? blk->isWritable() : blk->isValid());
|
||||||
assert(pkt->getOffset(blkSize) + pkt->getSize() <= blkSize);
|
assert(pkt->isWrite() || pkt->isReadWrite() || pkt->isRead());
|
||||||
|
assert(pkt->getOffset(blkSize) + pkt->getSize() <= blkSize);
|
||||||
|
|
||||||
if (pkt->isWrite()) {
|
if (pkt->isWrite()) {
|
||||||
if (blk->checkWrite(pkt)) {
|
if (blk->checkWrite(pkt)) {
|
||||||
blk->status |= BlkDirty;
|
blk->status |= BlkDirty;
|
||||||
pkt->writeDataToBlock(blk->data, blkSize);
|
pkt->writeDataToBlock(blk->data, blkSize);
|
||||||
}
|
|
||||||
} else if (pkt->isReadWrite()) {
|
|
||||||
cmpAndSwap(blk, pkt);
|
|
||||||
} else {
|
|
||||||
if (pkt->isLocked()) {
|
|
||||||
blk->trackLoadLocked(pkt);
|
|
||||||
}
|
|
||||||
pkt->setDataFromBlock(blk->data, blkSize);
|
|
||||||
}
|
}
|
||||||
|
} else if (pkt->isReadWrite()) {
|
||||||
return true;
|
cmpAndSwap(blk, pkt);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
if (pkt->isLocked()) {
|
||||||
|
blk->trackLoadLocked(pkt);
|
||||||
|
}
|
||||||
|
pkt->setDataFromBlock(blk->data, blkSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class TagStore, class Coherence>
|
|
||||||
bool
|
|
||||||
Cache<TagStore,Coherence>::satisfyTarget(MSHR::Target *target, BlkType *blk)
|
|
||||||
{
|
|
||||||
assert(target != NULL);
|
|
||||||
assert(target->isCpuSide());
|
|
||||||
return satisfyCpuSideRequest(target->pkt, blk);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TagStore, class Coherence>
|
template<class TagStore, class Coherence>
|
||||||
bool
|
bool
|
||||||
Cache<TagStore,Coherence>::satisfyMSHR(MSHR *mshr, PacketPtr pkt,
|
Cache<TagStore,Coherence>::satisfyMSHR(MSHR *mshr, PacketPtr pkt,
|
||||||
|
@ -611,37 +599,42 @@ Cache<TagStore,Coherence>::satisfyMSHR(MSHR *mshr, PacketPtr pkt,
|
||||||
while (mshr->hasTargets()) {
|
while (mshr->hasTargets()) {
|
||||||
MSHR::Target *target = mshr->getTarget();
|
MSHR::Target *target = mshr->getTarget();
|
||||||
|
|
||||||
if (!satisfyTarget(target, blk)) {
|
if (target->isCpuSide()) {
|
||||||
// Invalid access, need to do another request
|
satisfyCpuSideRequest(target->pkt, blk);
|
||||||
// can occur if block is invalidated, or not correct
|
// How many bytes pass the first request is this one
|
||||||
// permissions
|
int transfer_offset =
|
||||||
MSHRQueue *mq = mshr->queue;
|
target->pkt->getOffset(blkSize) - initial_offset;
|
||||||
mq->markPending(mshr);
|
if (transfer_offset < 0) {
|
||||||
mshr->order = order++;
|
transfer_offset += blkSize;
|
||||||
requestMemSideBus((RequestCause)mq->index, pkt->finishTime);
|
}
|
||||||
return false;
|
|
||||||
|
// If critical word (no offset) return first word time
|
||||||
|
Tick completion_time = tags->getHitLatency() +
|
||||||
|
transfer_offset ? pkt->finishTime : pkt->firstWordTime;
|
||||||
|
|
||||||
|
if (!target->pkt->req->isUncacheable()) {
|
||||||
|
missLatency[target->pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/] +=
|
||||||
|
completion_time - target->time;
|
||||||
|
}
|
||||||
|
target->pkt->makeTimingResponse();
|
||||||
|
cpuSidePort->respond(target->pkt, completion_time);
|
||||||
|
} else {
|
||||||
|
// response to snoop request
|
||||||
|
DPRINTF(Cache, "processing deferred snoop...\n");
|
||||||
|
handleSnoop(target->pkt, blk, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// How many bytes pass the first request is this one
|
|
||||||
int transfer_offset = target->pkt->getOffset(blkSize) - initial_offset;
|
|
||||||
if (transfer_offset < 0) {
|
|
||||||
transfer_offset += blkSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If critical word (no offset) return first word time
|
|
||||||
Tick completion_time = tags->getHitLatency() +
|
|
||||||
transfer_offset ? pkt->finishTime : pkt->firstWordTime;
|
|
||||||
|
|
||||||
if (!target->pkt->req->isUncacheable()) {
|
|
||||||
missLatency[target->pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/] +=
|
|
||||||
completion_time - target->time;
|
|
||||||
}
|
|
||||||
target->pkt->makeTimingResponse();
|
|
||||||
cpuSidePort->respond(target->pkt, completion_time);
|
|
||||||
mshr->popTarget();
|
mshr->popTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mshr->promoteDeferredTargets()) {
|
||||||
|
MSHRQueue *mq = mshr->queue;
|
||||||
|
mq->markPending(mshr);
|
||||||
|
mshr->order = order++;
|
||||||
|
requestMemSideBus((RequestCause)mq->index, pkt->finishTime);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -653,6 +646,7 @@ Cache<TagStore,Coherence>::handleResponse(PacketPtr pkt)
|
||||||
Tick time = curTick + hitLatency;
|
Tick time = curTick + hitLatency;
|
||||||
MSHR *mshr = dynamic_cast<MSHR*>(pkt->senderState);
|
MSHR *mshr = dynamic_cast<MSHR*>(pkt->senderState);
|
||||||
assert(mshr);
|
assert(mshr);
|
||||||
|
|
||||||
if (pkt->result == Packet::Nacked) {
|
if (pkt->result == Packet::Nacked) {
|
||||||
//pkt->reinitFromRequest();
|
//pkt->reinitFromRequest();
|
||||||
warn("NACKs from devices not connected to the same bus "
|
warn("NACKs from devices not connected to the same bus "
|
||||||
|
@ -661,7 +655,7 @@ Cache<TagStore,Coherence>::handleResponse(PacketPtr pkt)
|
||||||
}
|
}
|
||||||
assert(pkt->result != Packet::BadAddress);
|
assert(pkt->result != Packet::BadAddress);
|
||||||
assert(pkt->result == Packet::Success);
|
assert(pkt->result == Packet::Success);
|
||||||
DPRINTF(Cache, "Handling reponse to %x\n", pkt->getAddr());
|
DPRINTF(Cache, "Handling response to %x\n", pkt->getAddr());
|
||||||
|
|
||||||
MSHRQueue *mq = mshr->queue;
|
MSHRQueue *mq = mshr->queue;
|
||||||
bool wasFull = mq->isFull();
|
bool wasFull = mq->isFull();
|
||||||
|
@ -883,7 +877,12 @@ Cache<TagStore,Coherence>::snoopTiming(PacketPtr pkt)
|
||||||
MSHR *mshr = mshrQueue.findMatch(blk_addr);
|
MSHR *mshr = mshrQueue.findMatch(blk_addr);
|
||||||
// better not be snooping a request that conflicts with something
|
// better not be snooping a request that conflicts with something
|
||||||
// we have outstanding...
|
// we have outstanding...
|
||||||
assert(!mshr || !mshr->inService);
|
if (mshr && mshr->inService) {
|
||||||
|
assert(mshr->getNumTargets() < numTarget); //handle later
|
||||||
|
mshr->allocateSnoopTarget(pkt);
|
||||||
|
assert(mshr->getNumTargets() < numTarget); //handle later
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//We also need to check the writeback buffers and handle those
|
//We also need to check the writeback buffers and handle those
|
||||||
std::vector<MSHR *> writebacks;
|
std::vector<MSHR *> writebacks;
|
||||||
|
@ -895,6 +894,9 @@ Cache<TagStore,Coherence>::snoopTiming(PacketPtr pkt)
|
||||||
for (int i=0; i<writebacks.size(); i++) {
|
for (int i=0; i<writebacks.size(); i++) {
|
||||||
mshr = writebacks[i];
|
mshr = writebacks[i];
|
||||||
assert(!mshr->isUncacheable());
|
assert(!mshr->isUncacheable());
|
||||||
|
assert(mshr->getNumTargets() == 1);
|
||||||
|
PacketPtr wb_pkt = mshr->getTarget()->pkt;
|
||||||
|
assert(wb_pkt->cmd == MemCmd::Writeback);
|
||||||
|
|
||||||
if (pkt->isRead()) {
|
if (pkt->isRead()) {
|
||||||
pkt->assertMemInhibit();
|
pkt->assertMemInhibit();
|
||||||
|
@ -906,7 +908,7 @@ Cache<TagStore,Coherence>::snoopTiming(PacketPtr pkt)
|
||||||
// the packet's invalidate flag is set...
|
// the packet's invalidate flag is set...
|
||||||
assert(pkt->isInvalidate());
|
assert(pkt->isInvalidate());
|
||||||
}
|
}
|
||||||
doTimingSupplyResponse(pkt, mshr->writeData);
|
doTimingSupplyResponse(pkt, wb_pkt->getPtr<uint8_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pkt->isInvalidate()) {
|
if (pkt->isInvalidate()) {
|
||||||
|
@ -1208,7 +1210,7 @@ Cache<TagStore,Coherence>::MemSidePort::sendPacket()
|
||||||
|
|
||||||
waitingOnRetry = !success;
|
waitingOnRetry = !success;
|
||||||
if (waitingOnRetry) {
|
if (waitingOnRetry) {
|
||||||
DPRINTF(CachePort, "%s now waiting on a retry\n", name());
|
DPRINTF(CachePort, "now waiting on a retry\n");
|
||||||
} else {
|
} else {
|
||||||
myCache()->markInService(mshr);
|
myCache()->markInService(mshr);
|
||||||
}
|
}
|
||||||
|
@ -1220,8 +1222,7 @@ Cache<TagStore,Coherence>::MemSidePort::sendPacket()
|
||||||
if (!waitingOnRetry) {
|
if (!waitingOnRetry) {
|
||||||
if (isBusRequested()) {
|
if (isBusRequested()) {
|
||||||
// more requests/writebacks: rerequest ASAP
|
// more requests/writebacks: rerequest ASAP
|
||||||
DPRINTF(CachePort, "%s still more MSHR requests to send\n",
|
DPRINTF(CachePort, "still more MSHR requests to send\n");
|
||||||
name());
|
|
||||||
sendEvent->schedule(curTick+1);
|
sendEvent->schedule(curTick+1);
|
||||||
} else if (!transmitList.empty()) {
|
} else if (!transmitList.empty()) {
|
||||||
// deferred packets: rerequest bus, but possibly not until later
|
// deferred packets: rerequest bus, but possibly not until later
|
||||||
|
|
94
src/mem/cache/miss/mshr.cc
vendored
94
src/mem/cache/miss/mshr.cc
vendored
|
@ -68,12 +68,16 @@ MSHR::allocate(Addr _addr, int _size, PacketPtr target)
|
||||||
// Don't know of a case where we would allocate a new MSHR for a
|
// Don't know of a case where we would allocate a new MSHR for a
|
||||||
// snoop (mem0-side request), so set cpuSide to true here.
|
// snoop (mem0-side request), so set cpuSide to true here.
|
||||||
targets.push_back(Target(target, true));
|
targets.push_back(Target(target, true));
|
||||||
|
assert(deferredTargets.empty());
|
||||||
|
deferredNeedsExclusive = false;
|
||||||
|
pendingInvalidate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MSHR::deallocate()
|
MSHR::deallocate()
|
||||||
{
|
{
|
||||||
assert(targets.empty());
|
assert(targets.empty());
|
||||||
|
assert(deferredTargets.empty());
|
||||||
assert(ntargets == 0);
|
assert(ntargets == 0);
|
||||||
inService = false;
|
inService = false;
|
||||||
//allocIter = NULL;
|
//allocIter = NULL;
|
||||||
|
@ -84,41 +88,77 @@ MSHR::deallocate()
|
||||||
* Adds a target to an MSHR
|
* Adds a target to an MSHR
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
MSHR::allocateTarget(PacketPtr target, bool cpuSide)
|
MSHR::allocateTarget(PacketPtr target)
|
||||||
{
|
{
|
||||||
//If we append an invalidate and we issued a read to the bus,
|
if (inService) {
|
||||||
//but now have some pending writes, we need to move
|
if (!deferredTargets.empty() || pendingInvalidate ||
|
||||||
//the invalidate to before the first non-read
|
(!needsExclusive && target->needsExclusive())) {
|
||||||
if (inService && !inServiceForExclusive && needsExclusive
|
// need to put on deferred list
|
||||||
&& !cpuSide && target->isInvalidate()) {
|
deferredTargets.push_back(Target(target, true));
|
||||||
std::list<Target> temp;
|
if (target->needsExclusive()) {
|
||||||
|
deferredNeedsExclusive = true;
|
||||||
while (!targets.empty()) {
|
}
|
||||||
if (targets.front().pkt->needsExclusive()) break;
|
} else {
|
||||||
//Place on top of temp stack
|
// still OK to append to outstanding request
|
||||||
temp.push_front(targets.front());
|
targets.push_back(Target(target, true));
|
||||||
//Remove from targets
|
}
|
||||||
targets.pop_front();
|
} else {
|
||||||
|
if (target->needsExclusive()) {
|
||||||
|
needsExclusive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Now that we have all the reads off until first non-read, we can
|
targets.push_back(Target(target, true));
|
||||||
//place the invalidate on
|
|
||||||
targets.push_front(Target(target, cpuSide));
|
|
||||||
|
|
||||||
//Now we pop off the temp_stack and put them back
|
|
||||||
while (!temp.empty()) {
|
|
||||||
targets.push_front(temp.front());
|
|
||||||
temp.pop_front();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
targets.push_back(Target(target, cpuSide));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
++ntargets;
|
++ntargets;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MSHR::allocateSnoopTarget(PacketPtr target)
|
||||||
|
{
|
||||||
|
assert(inService); // don't bother to call otherwise
|
||||||
|
|
||||||
|
if (pendingInvalidate) {
|
||||||
|
// a prior snoop has already appended an invalidation, so
|
||||||
|
// logically we don't have the block anymore...
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needsExclusive) {
|
||||||
|
// We're awaiting an exclusive copy, so ownership is pending.
|
||||||
|
// It's up to us to respond once the data arrives.
|
||||||
|
target->assertMemInhibit();
|
||||||
|
} else if (target->needsExclusive()) {
|
||||||
|
// This transaction will take away our pending copy
|
||||||
|
pendingInvalidate = true;
|
||||||
|
} else {
|
||||||
|
// If we're not going to supply data or perform an
|
||||||
|
// invalidation, we don't need to save this.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
targets.push_back(Target(target, false));
|
||||||
|
++ntargets;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
MSHR::promoteDeferredTargets()
|
||||||
|
{
|
||||||
|
if (deferredTargets.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(targets.empty());
|
||||||
|
targets = deferredTargets;
|
||||||
|
deferredTargets.clear();
|
||||||
assert(targets.size() == ntargets);
|
assert(targets.size() == ntargets);
|
||||||
|
|
||||||
needsExclusive = needsExclusive || target->needsExclusive();
|
needsExclusive = deferredNeedsExclusive;
|
||||||
|
pendingInvalidate = false;
|
||||||
|
deferredNeedsExclusive = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
17
src/mem/cache/miss/mshr.hh
vendored
17
src/mem/cache/miss/mshr.hh
vendored
|
@ -85,9 +85,6 @@ class MSHR : public Packet::SenderState
|
||||||
/** Size of the request. */
|
/** Size of the request. */
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
/** Data associated with the request (if a write). */
|
|
||||||
uint8_t *writeData;
|
|
||||||
|
|
||||||
/** True if the request has been sent to the bus. */
|
/** True if the request has been sent to the bus. */
|
||||||
bool inService;
|
bool inService;
|
||||||
|
|
||||||
|
@ -95,12 +92,13 @@ class MSHR : public Packet::SenderState
|
||||||
bool isCacheFill;
|
bool isCacheFill;
|
||||||
/** True if we need to get an exclusive copy of the block. */
|
/** True if we need to get an exclusive copy of the block. */
|
||||||
bool needsExclusive;
|
bool needsExclusive;
|
||||||
|
|
||||||
/** True if the request is uncacheable */
|
/** True if the request is uncacheable */
|
||||||
bool _isUncacheable;
|
bool _isUncacheable;
|
||||||
|
|
||||||
/** True if the request that has been sent to the bus is for en
|
bool deferredNeedsExclusive;
|
||||||
* exclusive copy. */
|
bool pendingInvalidate;
|
||||||
bool inServiceForExclusive;
|
|
||||||
/** Thread number of the miss. */
|
/** Thread number of the miss. */
|
||||||
short threadNum;
|
short threadNum;
|
||||||
/** The number of currently allocated targets. */
|
/** The number of currently allocated targets. */
|
||||||
|
@ -124,6 +122,8 @@ private:
|
||||||
/** List of all requests that match the address */
|
/** List of all requests that match the address */
|
||||||
TargetList targets;
|
TargetList targets;
|
||||||
|
|
||||||
|
TargetList deferredTargets;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
bool isUncacheable() { return _isUncacheable; }
|
bool isUncacheable() { return _isUncacheable; }
|
||||||
|
@ -153,7 +153,8 @@ public:
|
||||||
* Add a request to the list of targets.
|
* Add a request to the list of targets.
|
||||||
* @param target The target.
|
* @param target The target.
|
||||||
*/
|
*/
|
||||||
void allocateTarget(PacketPtr target, bool cpuSide);
|
void allocateTarget(PacketPtr target);
|
||||||
|
void allocateSnoopTarget(PacketPtr target);
|
||||||
|
|
||||||
/** A simple constructor. */
|
/** A simple constructor. */
|
||||||
MSHR();
|
MSHR();
|
||||||
|
@ -201,6 +202,8 @@ public:
|
||||||
return tgt->isCpuSide() && !tgt->pkt->needsResponse();
|
return tgt->isCpuSide() && !tgt->pkt->needsResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool promoteDeferredTargets();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints the contents of this MSHR to stderr.
|
* Prints the contents of this MSHR to stderr.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue