+
+ /**
+ * Use the provided packet and the source to update the
+ * flags of this TargetList.
+ *
+ * @param pkt Packet considered for the flag update
+ * @param source Indicates the source of the packet
+ * @param alloc_on_fill Whether the pkt would allocate on a fill
+ */
+ void updateFlags(PacketPtr pkt, Target::Source source,
+ bool alloc_on_fill);
+
+ /**
+ * 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();
+ }
+
+ void resetFlags() {
+ canMergeWrites = true;
+ std::fill(writesBitmap.begin(), writesBitmap.end(), false);
+
+ needsWritable = false;
+ hasUpgrade = false;
+ allocOnFill = false;
+ hasFromCache = false;
+ }
+
+ /**
+ * Goes through the list of targets and uses them to populate
+ * the flags of this TargetList. When the function returns the
+ * flags are consistent with the properties of packets in the
+ * list.
+ */
+ void populateFlags();
+
+ /**
+ * 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)
+ {
+ // 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()) {
+ // Avoid merging requests with special flags (e.g.,
+ // strictly ordered)
+ const Request::FlagsType no_merge_flags =
+ Request::UNCACHEABLE | Request::STRICT_ORDER |
+ Request::MMAPPED_IPR | Request::PRIVILEGED |
+ Request::LLSC | Request::MEM_SWAP |
+ Request::MEM_SWAP_COND | Request::SECURE;
+ const auto &req_flags = pkt->req->getFlags();
+ bool compat_write = pkt->isWrite() &&
+ !req_flags.isSet(no_merge_flags);
+ canMergeWrites &= compat_write;
+
+ // if this request is the first target in this list
+ // and additionally a whole-line write, we need to
+ // service it as a whole-line even if we won't allow
+ // any further merging (e.g., SECURE whole line
+ // write).
+ bool first_write = pkt->isWrite() && (size() == 0);
+ if (first_write || compat_write) {
+ auto offset = pkt->getOffset(blkSize);
+ auto begin = writesBitmap.begin() + offset;
+ std::fill(begin, begin + pkt->getSize(), true);
+ }
+ }
+ }
+
+ /**
+ * Tests if the flags of this TargetList have their default
+ * values.
+ *
+ * @return True if the TargetList are reset, false otherwise.
+ */
+ bool isReset() const {
+ return !needsWritable && !hasUpgrade && !allocOnFill &&
+ !hasFromCache && canMergeWrites;
+ }
+
+ /**
+ * 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
+ * @param readTime Tick at which the packet is processed by this cache
+ * @param order A counter giving a unique id to each target
+ * @param source Indicates the source agent of the packet
+ * @param markPending Set for deferred targets or pending MSHRs
+ * @param alloc_on_fill Whether it should allocate on a fill
+ */