First Pass At Cmp/Swap in caches
--HG-- extra : convert_revision : 211bfb7c6a59e9e120dae1600d4754baaf231332
This commit is contained in:
parent
c6e85efc50
commit
6b8cd9d06d
3 changed files with 65 additions and 6 deletions
6
src/mem/cache/cache.hh
vendored
6
src/mem/cache/cache.hh
vendored
|
@ -227,6 +227,12 @@ class Cache : public BaseCache
|
||||||
BlkType* handleAccess(PacketPtr &pkt, int & lat,
|
BlkType* handleAccess(PacketPtr &pkt, int & lat,
|
||||||
PacketList & writebacks, bool update = true);
|
PacketList & writebacks, bool update = true);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Handle doing the Compare and Swap function for SPARC.
|
||||||
|
*/
|
||||||
|
void cmpAndSwap(BlkType *blk, PacketPtr &pkt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populates a cache block and handles all outstanding requests for the
|
* Populates a cache block and handles all outstanding requests for the
|
||||||
* satisfied fill request. This version takes an MSHR pointer and uses its
|
* satisfied fill request. This version takes an MSHR pointer and uses its
|
||||||
|
|
60
src/mem/cache/cache_impl.hh
vendored
60
src/mem/cache/cache_impl.hh
vendored
|
@ -122,12 +122,15 @@ Cache<TagStore,Coherence>::handleAccess(PacketPtr &pkt, int & lat,
|
||||||
if (blk != NULL) {
|
if (blk != NULL) {
|
||||||
|
|
||||||
if (!update) {
|
if (!update) {
|
||||||
|
|
||||||
if (pkt->isWrite()){
|
if (pkt->isWrite()){
|
||||||
assert(offset < blkSize);
|
assert(offset < blkSize);
|
||||||
assert(pkt->getSize() <= blkSize);
|
assert(pkt->getSize() <= blkSize);
|
||||||
assert(offset+pkt->getSize() <= blkSize);
|
assert(offset+pkt->getSize() <= blkSize);
|
||||||
std::memcpy(blk->data + offset, pkt->getPtr<uint8_t>(),
|
std::memcpy(blk->data + offset, pkt->getPtr<uint8_t>(),
|
||||||
pkt->getSize());
|
pkt->getSize());
|
||||||
|
} else if (pkt->isReadWrite()) {
|
||||||
|
cmpAndSwap(blk, pkt);
|
||||||
} else if (!(pkt->flags & SATISFIED)) {
|
} else if (!(pkt->flags & SATISFIED)) {
|
||||||
pkt->flags |= SATISFIED;
|
pkt->flags |= SATISFIED;
|
||||||
pkt->result = Packet::Success;
|
pkt->result = Packet::Success;
|
||||||
|
@ -154,7 +157,8 @@ Cache<TagStore,Coherence>::handleAccess(PacketPtr &pkt, int & lat,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pkt->isWrite() && blk->isWritable()) ||
|
if ((pkt->isReadWrite() && blk->isWritable()) ||
|
||||||
|
(pkt->isWrite() && blk->isWritable()) ||
|
||||||
(pkt->isRead() && blk->isValid())) {
|
(pkt->isRead() && blk->isValid())) {
|
||||||
|
|
||||||
// We are satisfying the request
|
// We are satisfying the request
|
||||||
|
@ -180,6 +184,8 @@ Cache<TagStore,Coherence>::handleAccess(PacketPtr &pkt, int & lat,
|
||||||
std::memcpy(blk->data + offset, pkt->getPtr<uint8_t>(),
|
std::memcpy(blk->data + offset, pkt->getPtr<uint8_t>(),
|
||||||
pkt->getSize());
|
pkt->getSize());
|
||||||
}
|
}
|
||||||
|
} else if (pkt->isReadWrite()) {
|
||||||
|
cmpAndSwap(blk, pkt);
|
||||||
} else {
|
} else {
|
||||||
assert(pkt->isRead());
|
assert(pkt->isRead());
|
||||||
if (pkt->req->isLocked()) {
|
if (pkt->req->isLocked()) {
|
||||||
|
@ -214,6 +220,44 @@ Cache<TagStore,Coherence>::handleAccess(PacketPtr &pkt, int & lat,
|
||||||
return blk;
|
return blk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class TagStore, class Coherence>
|
||||||
|
void
|
||||||
|
Cache<TagStore,Coherence>::cmpAndSwap(BlkType *blk, PacketPtr &pkt){
|
||||||
|
uint64_t overwrite_val;
|
||||||
|
bool overwrite_mem;
|
||||||
|
uint64_t condition_val64;
|
||||||
|
uint32_t condition_val32;
|
||||||
|
|
||||||
|
int offset = tags->extractBlkOffset(pkt->getAddr());
|
||||||
|
|
||||||
|
assert(sizeof(uint64_t) >= pkt->getSize());
|
||||||
|
|
||||||
|
overwrite_mem = true;
|
||||||
|
// keep a copy of our possible write value, and copy what is at the
|
||||||
|
// memory address into the packet
|
||||||
|
std::memcpy(&overwrite_val, pkt->getPtr<uint8_t>(), pkt->getSize());
|
||||||
|
std::memcpy(pkt->getPtr<uint8_t>(), blk->data + offset,
|
||||||
|
pkt->getSize());
|
||||||
|
|
||||||
|
if (pkt->req->isCondSwap()) {
|
||||||
|
if (pkt->getSize() == sizeof(uint64_t)) {
|
||||||
|
condition_val64 = pkt->req->getExtraData();
|
||||||
|
overwrite_mem = !std::memcmp(&condition_val64, blk->data + offset,
|
||||||
|
sizeof(uint64_t));
|
||||||
|
} else if (pkt->getSize() == sizeof(uint32_t)) {
|
||||||
|
condition_val32 = (uint32_t)pkt->req->getExtraData();
|
||||||
|
overwrite_mem = !std::memcmp(&condition_val32, blk->data + offset,
|
||||||
|
sizeof(uint32_t));
|
||||||
|
} else
|
||||||
|
panic("Invalid size for conditional read/write\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (overwrite_mem)
|
||||||
|
std::memcpy(blk->data + offset,
|
||||||
|
&overwrite_val, pkt->getSize());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
template<class TagStore, class Coherence>
|
template<class TagStore, class Coherence>
|
||||||
typename Cache<TagStore,Coherence>::BlkType*
|
typename Cache<TagStore,Coherence>::BlkType*
|
||||||
Cache<TagStore,Coherence>::handleFill(BlkType *blk, PacketPtr &pkt,
|
Cache<TagStore,Coherence>::handleFill(BlkType *blk, PacketPtr &pkt,
|
||||||
|
@ -244,8 +288,9 @@ Cache<TagStore,Coherence>::handleFill(BlkType *blk, PacketPtr &pkt,
|
||||||
blk = NULL;
|
blk = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blk && (target->isWrite() ? blk->isWritable() : blk->isValid())) {
|
if (blk && ((target->isWrite() || target->isReadWrite()) ?
|
||||||
assert(target->isWrite() || target->isRead());
|
blk->isWritable() : blk->isValid())) {
|
||||||
|
assert(target->isWrite() || target->isReadWrite() || target->isRead());
|
||||||
assert(target->getOffset(blkSize) + target->getSize() <= blkSize);
|
assert(target->getOffset(blkSize) + target->getSize() <= blkSize);
|
||||||
if (target->isWrite()) {
|
if (target->isWrite()) {
|
||||||
if (blk->checkWrite(pkt->req)) {
|
if (blk->checkWrite(pkt->req)) {
|
||||||
|
@ -253,6 +298,8 @@ Cache<TagStore,Coherence>::handleFill(BlkType *blk, PacketPtr &pkt,
|
||||||
std::memcpy(blk->data + target->getOffset(blkSize),
|
std::memcpy(blk->data + target->getOffset(blkSize),
|
||||||
target->getPtr<uint8_t>(), target->getSize());
|
target->getPtr<uint8_t>(), target->getSize());
|
||||||
}
|
}
|
||||||
|
} else if (target->isReadWrite()) {
|
||||||
|
cmpAndSwap(blk, pkt);
|
||||||
} else {
|
} else {
|
||||||
if (pkt->req->isLocked()) {
|
if (pkt->req->isLocked()) {
|
||||||
blk->trackLoadLocked(pkt->req);
|
blk->trackLoadLocked(pkt->req);
|
||||||
|
@ -332,8 +379,9 @@ Cache<TagStore,Coherence>::handleFill(BlkType *blk, MSHR * mshr,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blk && (target->isWrite() ? blk->isWritable() : blk->isValid())) {
|
if (blk && ((target->isWrite() || target->isReadWrite()) ?
|
||||||
assert(target->isWrite() || target->isRead());
|
blk->isWritable() : blk->isValid())) {
|
||||||
|
assert(target->isWrite() || target->isRead() || target->isReadWrite() );
|
||||||
assert(target->getOffset(blkSize) + target->getSize() <= blkSize);
|
assert(target->getOffset(blkSize) + target->getSize() <= blkSize);
|
||||||
if (target->isWrite()) {
|
if (target->isWrite()) {
|
||||||
if (blk->checkWrite(pkt->req)) {
|
if (blk->checkWrite(pkt->req)) {
|
||||||
|
@ -341,6 +389,8 @@ Cache<TagStore,Coherence>::handleFill(BlkType *blk, MSHR * mshr,
|
||||||
std::memcpy(blk->data + target->getOffset(blkSize),
|
std::memcpy(blk->data + target->getOffset(blkSize),
|
||||||
target->getPtr<uint8_t>(), target->getSize());
|
target->getPtr<uint8_t>(), target->getSize());
|
||||||
}
|
}
|
||||||
|
} else if (target->isReadWrite()) {
|
||||||
|
cmpAndSwap(blk, pkt);
|
||||||
} else {
|
} else {
|
||||||
if (target->req->isLocked()) {
|
if (target->req->isLocked()) {
|
||||||
blk->trackLoadLocked(target->req);
|
blk->trackLoadLocked(target->req);
|
||||||
|
|
|
@ -295,9 +295,12 @@ CoherenceProtocol::CoherenceProtocol(const string &name,
|
||||||
tt[Invalid][MC::ReadReq].onRequest(MC::ReadReq);
|
tt[Invalid][MC::ReadReq].onRequest(MC::ReadReq);
|
||||||
// we only support write allocate right now
|
// we only support write allocate right now
|
||||||
tt[Invalid][MC::WriteReq].onRequest(MC::ReadExReq);
|
tt[Invalid][MC::WriteReq].onRequest(MC::ReadExReq);
|
||||||
|
tt[Invalid][MC::SwapReq].onRequest(MC::ReadExReq);
|
||||||
tt[Shared][MC::WriteReq].onRequest(writeToSharedCmd);
|
tt[Shared][MC::WriteReq].onRequest(writeToSharedCmd);
|
||||||
|
tt[Shared][MC::SwapReq].onRequest(writeToSharedCmd);
|
||||||
if (hasOwned) {
|
if (hasOwned) {
|
||||||
tt[Owned][MC::WriteReq].onRequest(writeToSharedCmd);
|
tt[Owned][MC::WriteReq].onRequest(writeToSharedCmd);
|
||||||
|
tt[Owned][MC::SwapReq].onRequest(writeToSharedCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prefetching causes a read
|
// Prefetching causes a read
|
||||||
|
|
Loading…
Reference in a new issue