diff options
author | Tuan Ta <qtt2@cornell.edu> | 2018-01-22 12:54:14 -0500 |
---|---|---|
committer | Tuan Ta <qtt2@cornell.edu> | 2018-06-14 22:41:11 +0000 |
commit | 7bab1d0aff897bc23b5677a51ae67b8cc32953dc (patch) | |
tree | b306210feabe295f3aeaad2c1ac4d7c4679b117c /src/mem/cache | |
parent | 74a8947fcb37ec4b3d43cf96740c474f0e3ffed8 (diff) | |
download | gem5-7bab1d0aff897bc23b5677a51ae67b8cc32953dc.tar.xz |
base,mem: Support AtomicOpFunctor in the classic memory system
AtomicOpFunctor can be used to implement atomic memory operations.
AtomicOpFunctor is captured inside a memory request and executed directly
in the memory hierarchy in a single step.
This patch enables AtomicOpFunctor pointers to be included in a memory
request and executed in a single step in the classic cache system.
This patch also makes the copy constructor of Request class do a deep
copy of AtomicOpFunctor object. This prevents a copy of a Request object
from accessing a deleted AtomicOpFunctor object.
Change-Id: I6649532b37f711e55f4552ad26893efeb300dd37
Reviewed-on: https://gem5-review.googlesource.com/8185
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
Diffstat (limited to 'src/mem/cache')
-rw-r--r-- | src/mem/cache/base.cc | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc index e43c3d920..a510bac8a 100644 --- a/src/mem/cache/base.cc +++ b/src/mem/cache/base.cc @@ -836,7 +836,22 @@ BaseCache::satisfyRequest(PacketPtr pkt, CacheBlk *blk, bool, bool) // Check RMW operations first since both isRead() and // isWrite() will be true for them if (pkt->cmd == MemCmd::SwapReq) { - cmpAndSwap(blk, pkt); + if (pkt->isAtomicOp()) { + // extract data from cache and save it into the data field in + // the packet as a return value from this atomic op + + int offset = tags->extractBlkOffset(pkt->getAddr()); + uint8_t *blk_data = blk->data + offset; + std::memcpy(pkt->getPtr<uint8_t>(), blk_data, pkt->getSize()); + + // execute AMO operation + (*(pkt->getAtomicOp()))(blk_data); + + // set block status to dirty + blk->status |= BlkDirty; + } else { + cmpAndSwap(blk, pkt); + } } else if (pkt->isWrite()) { // we have the block in a writable state and can go ahead, // note that the line may be also be considered writable in |