40a41
> * Nikos Nikoleris
54a56
> #include <vector>
59a62
> #include "mem/request.hh"
117a121,123
> /** Track if we sent this as a whole line write or not */
> bool wasWholeLineWrite;
>
189a196,209
> /**
> * Reset state
> *
> * @param blk_addr Address of the cache block
> * @param blk_size Size of the cache block
> */
> void init(Addr blk_addr, Addr blk_size) {
> blkAddr = blk_addr;
> blkSize = blk_size;
> writesBitmap.resize(blk_size);
>
> resetFlags();
> }
>
190a211,213
> onlyWrites = true;
> std::fill(writesBitmap.begin(), writesBitmap.end(), false);
>
205a229,258
> * Add the specified packet in the TargetList. This function
> * stores information related to the added packet and updates
> * accordingly the flags.
> *
> * @param pkt Packet considered for adding
> */
> void updateWriteFlags(PacketPtr pkt) {
> const Request::FlagsType noMergeFlags =
> Request::UNCACHEABLE |
> Request::STRICT_ORDER | Request::MMAPPED_IPR |
> Request::PRIVILEGED | Request::LLSC |
> Request::MEM_SWAP | Request::MEM_SWAP_COND |
> Request::SECURE;
>
> // if we have already seen writes for the full block stop
> // here, this might be a full line write followed by
> // other compatible requests (e.g., reads)
> if (!isWholeLineWrite()) {
> bool can_merge_write = pkt->isWrite() &&
> ((pkt->req->getFlags() & noMergeFlags) == 0);
> onlyWrites &= can_merge_write;
> if (onlyWrites) {
> auto offset = pkt->getOffset(blkSize);
> auto begin = writesBitmap.begin() + offset;
> std::fill(begin, begin + pkt->getSize(), true);
> }
> }
> }
>
> /**
207a261,262
> *
> * @return True if the TargetList are reset, false otherwise.
211c266
< !hasFromCache;
---
> !hasFromCache && onlyWrites;
227,228c282
< Target::Source source, bool markPending,
< bool alloc_on_fill);
---
> Target::Source source, bool markPending, bool alloc_on_fill);
240a295,327
>
> /**
> * Check if this list contains only compatible writes, and if they
> * span the entire cache line. This is used as part of the
> * miss-packet creation. Note that new requests may arrive after a
> * miss-packet has been created, and for the fill we therefore use
> * the wasWholeLineWrite field.
> */
> bool isWholeLineWrite() const
> {
> return onlyWrites &&
> std::all_of(writesBitmap.begin(),
> writesBitmap.end(), [](bool i) { return i; });
> }
>
> private:
> /** Address of the cache block for this list of targets. */
> Addr blkAddr;
>
> /** Size of the cache block. */
> Addr blkSize;
>
> /** Are we only dealing with writes. */
> bool onlyWrites;
>
> // NOTE: std::vector<bool> might not meet satisfy the
> // ForwardIterator requirement and therefore cannot be used
> // for writesBitmap.
> /**
> * Track which bytes are written by requests in this target
> * list.
> */
> std::vector<char> writesBitmap;
317a405,414
> /**
> * Check if this MSHR contains only compatible writes, and if they
> * span the entire cache line. This is used as part of the
> * miss-packet creation. Note that new requests may arrive after a
> * miss-packet has been created, and for the fill we therefore use
> * the wasWholeLineWrite field.
> */
> bool isWholeLineWrite() const {
> return targets.isWholeLineWrite();
> }