+ void clearLoadLocks(const RequestPtr &req)
+ {
+ auto l = lockList.begin();
+ while (l != lockList.end()) {
+ if (l->intersects(req) && l->contextId != req->contextId()) {
+ l = lockList.erase(l);
+ } else {
+ ++l;
+ }
+ }
+ }
+
+ /**
+ * Pretty-print tag, set and way, and interpret state bits to readable form
+ * including mapping to a MOESI state.
+ *
+ * @return string with basic state information
+ */
+ virtual std::string print() const
+ {
+ /**
+ * state M O E S I
+ * writable 1 0 1 0 0
+ * dirty 1 1 0 0 0
+ * valid 1 1 1 1 0
+ *
+ * state writable dirty valid
+ * M 1 1 1
+ * O 0 1 1
+ * E 1 0 1
+ * S 0 0 1
+ * I 0 0 0
+ *
+ * Note that only one cache ever has a block in Modified or
+ * Owned state, i.e., only one cache owns the block, or
+ * equivalently has the BlkDirty bit set. However, multiple
+ * caches on the same path to memory can have a block in the
+ * Exclusive state (despite the name). Exclusive means this
+ * cache has the only copy at this level of the hierarchy,
+ * i.e., there may be copies in caches above this cache (in
+ * various states), but there are no peers that have copies on
+ * this branch of the hierarchy, and no caches at or above
+ * this level on any other branch have copies either.
+ **/
+ unsigned state = isWritable() << 2 | isDirty() << 1 | isValid();
+ char s = '?';
+ switch (state) {
+ case 0b111: s = 'M'; break;
+ case 0b011: s = 'O'; break;
+ case 0b101: s = 'E'; break;
+ case 0b001: s = 'S'; break;
+ case 0b000: s = 'I'; break;
+ default: s = 'T'; break; // @TODO add other types
+ }
+ return csprintf("state: %x (%c) valid: %d writable: %d readable: %d "
+ "dirty: %d | tag: %#x set: %#x way: %#x", status, s,
+ isValid(), isWritable(), isReadable(), isDirty(), tag,
+ getSet(), getWay());
+ }