Nikos Nikoleris has uploaded this change for review. ( https://gem5-review.googlesource.com/10425

Change subject: mem-cache: Refactor the recvAtomic function
......................................................................

mem-cache: Refactor the recvAtomic function

The recvAtomic function in the cache handles atomic requests. Over
time, recvAtomic has grown in complexity and code size. This change
factors out some of its functionality in a separate functiona. The new
functions handles atomic requests that miss.

Change-Id: If77d2de1e3e802e1da37f889f68910e700c59209
---
M src/mem/cache/cache.cc
M src/mem/cache/cache.hh
2 files changed, 100 insertions(+), 76 deletions(-)



diff --git a/src/mem/cache/cache.cc b/src/mem/cache/cache.cc
index 79e7613..9ef5bfd 100644
--- a/src/mem/cache/cache.cc
+++ b/src/mem/cache/cache.cc
@@ -1073,6 +1073,88 @@
 }


+Cycles
+Cache::handleAtomicReqMiss(PacketPtr pkt, CacheBlk *blk,
+                           PacketList &writebacks)
+{
+    // deal with the packets that go through the write path of
+    // the cache, i.e. any evictions and writes
+    if (pkt->isEviction() || pkt->cmd == MemCmd::WriteClean ||
+        (pkt->req->isUncacheable() && pkt->isWrite())) {
+        return ticksToCycles(memSidePort->sendAtomic(pkt));
+    }
+
+    // only misses left
+
+    PacketPtr bus_pkt = createMissPacket(pkt, blk, pkt->needsWritable());
+
+    bool is_forward = (bus_pkt == nullptr);
+
+    if (is_forward) {
+        // just forwarding the same request to the next level
+        // no local cache operation involved
+        bus_pkt = pkt;
+    }
+
+    DPRINTF(Cache, "%s: Sending an atomic %s\n", __func__,
+            bus_pkt->print());
+
+#if TRACING_ON
+    CacheBlk::State old_state = blk ? blk->status : 0;
+#endif
+
+    Cycles latency = ticksToCycles(memSidePort->sendAtomic(bus_pkt));
+
+    bool is_invalidate = bus_pkt->isInvalidate();
+
+    // We are now dealing with the response handling
+    DPRINTF(Cache, "%s: Receive response: %s in state %i\n", __func__,
+            bus_pkt->print(), old_state);
+
+    // If packet was a forward, the response (if any) is already
+    // in place in the bus_pkt == pkt structure, so we don't need
+    // to do anything.  Otherwise, use the separate bus_pkt to
+    // generate response to pkt and then delete it.
+    if (!is_forward) {
+        if (pkt->needsResponse()) {
+            assert(bus_pkt->isResponse());
+            if (bus_pkt->isError()) {
+                pkt->makeAtomicResponse();
+                pkt->copyError(bus_pkt);
+            } else if (pkt->cmd == MemCmd::WriteLineReq) {
+                // note the use of pkt, not bus_pkt here.
+
+                // write-line request to the cache that promoted
+                // the write to a whole line
+                blk = handleFill(pkt, blk, writebacks,
+                                 allocOnFill(pkt->cmd));
+                assert(blk != NULL);
+                is_invalidate = false;
+                satisfyRequest(pkt, blk);
+            } else if (bus_pkt->isRead() ||
+                       bus_pkt->cmd == MemCmd::UpgradeResp) {
+                // we're updating cache state to allow us to
+                // satisfy the upstream request from the cache
+                blk = handleFill(bus_pkt, blk, writebacks,
+                                 allocOnFill(pkt->cmd));
+                satisfyRequest(pkt, blk);
+                maintainClusivity(pkt->fromCache(), blk);
+            } else {
+                // we're satisfying the upstream request without
+                // modifying cache state, e.g., a write-through
+                pkt->makeAtomicResponse();
+            }
+        }
+        delete bus_pkt;
+    }
+
+    if (is_invalidate && blk && blk->isValid()) {
+        invalidateBlock(blk);
+    }
+
+    return latency;
+}
+
 Tick
 Cache::recvAtomic(PacketPtr pkt)
 {
@@ -1124,84 +1206,10 @@
     // handle writebacks resulting from the access here to ensure they
     // logically proceed anything happening below
     doWritebacksAtomic(writebacks);
+    assert(writebacks.empty());

     if (!satisfied) {
-        // MISS
-
-        // deal with the packets that go through the write path of
-        // the cache, i.e. any evictions and writes
-        if (pkt->isEviction() || pkt->cmd == MemCmd::WriteClean ||
-            (pkt->req->isUncacheable() && pkt->isWrite())) {
-            lat += ticksToCycles(memSidePort->sendAtomic(pkt));
-            return lat * clockPeriod();
-        }
-        // only misses left
-
- PacketPtr bus_pkt = createMissPacket(pkt, blk, pkt->needsWritable());
-
-        bool is_forward = (bus_pkt == nullptr);
-
-        if (is_forward) {
-            // just forwarding the same request to the next level
-            // no local cache operation involved
-            bus_pkt = pkt;
-        }
-
-        DPRINTF(Cache, "%s: Sending an atomic %s\n", __func__,
-                bus_pkt->print());
-
-#if TRACING_ON
-        CacheBlk::State old_state = blk ? blk->status : 0;
-#endif
-
-        lat += ticksToCycles(memSidePort->sendAtomic(bus_pkt));
-
-        bool is_invalidate = bus_pkt->isInvalidate();
-
-        // We are now dealing with the response handling
-        DPRINTF(Cache, "%s: Receive response: %s in state %i\n", __func__,
-                bus_pkt->print(), old_state);
-
-        // If packet was a forward, the response (if any) is already
-        // in place in the bus_pkt == pkt structure, so we don't need
-        // to do anything.  Otherwise, use the separate bus_pkt to
-        // generate response to pkt and then delete it.
-        if (!is_forward) {
-            if (pkt->needsResponse()) {
-                assert(bus_pkt->isResponse());
-                if (bus_pkt->isError()) {
-                    pkt->makeAtomicResponse();
-                    pkt->copyError(bus_pkt);
-                } else if (pkt->cmd == MemCmd::WriteLineReq) {
-                    // note the use of pkt, not bus_pkt here.
-
-                    // write-line request to the cache that promoted
-                    // the write to a whole line
-                    blk = handleFill(pkt, blk, writebacks,
-                                     allocOnFill(pkt->cmd));
-                    assert(blk != NULL);
-                    is_invalidate = false;
-                    satisfyRequest(pkt, blk);
-                } else if (bus_pkt->isRead() ||
-                           bus_pkt->cmd == MemCmd::UpgradeResp) {
-                    // we're updating cache state to allow us to
-                    // satisfy the upstream request from the cache
-                    blk = handleFill(bus_pkt, blk, writebacks,
-                                     allocOnFill(pkt->cmd));
-                    satisfyRequest(pkt, blk);
-                    maintainClusivity(pkt->fromCache(), blk);
-                } else {
-                    // we're satisfying the upstream request without
-                    // modifying cache state, e.g., a write-through
-                    pkt->makeAtomicResponse();
-                }
-            }
-            delete bus_pkt;
-        }
-
-        if (is_invalidate && blk && blk->isValid()) {
-            invalidateBlock(blk);
-        }
+        lat += handleAtomicReqMiss(pkt, blk, writebacks);
     }

     // Note that we don't invoke the prefetcher at all in atomic mode.
diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh
index 650f760..a90ffd5 100644
--- a/src/mem/cache/cache.hh
+++ b/src/mem/cache/cache.hh
@@ -422,6 +422,22 @@
      */
     void recvTimingSnoopResp(PacketPtr pkt);

+
+    /**
+     * Handle a request in atomic mode that missed in this cache
+     *
+     * Creates a downstream request, sends it to the memory below and
+     * handles the response. As we are in atomic mode all operations
+     * are performed immediately.
+     *
+     * pkt The packet with the requests
+     * @blk The referenced block
+     * @writebacks A list with packets for any performed writebacks
+     * @return Cycles for handling the request
+     */
+    Cycles handleAtomicReqMiss(PacketPtr pkt, CacheBlk *blk,
+                               PacketList &writebacks);
+
     /**
      * Performs the access specified by the request.
      * @param pkt The request to perform.

--
To view, visit https://gem5-review.googlesource.com/10425
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: If77d2de1e3e802e1da37f889f68910e700c59209
Gerrit-Change-Number: 10425
Gerrit-PatchSet: 1
Gerrit-Owner: Nikos Nikoleris <nikos.nikole...@arm.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to