1069a1070,1159
> 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())) {
> Cycles latency = ticksToCycles(memSidePort->sendAtomic(pkt));
>
> // at this point, if the request was an uncacheable write
> // request, it has been satisfied by a memory below and the
> // packet carries the response back
> assert(!(pkt->req->isUncacheable() && pkt->isWrite()) ||
> pkt->isResponse());
>
> return latency;
> }
>
> // 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;
> }
>
1120a1211
> assert(writebacks.empty());
1123,1198c1214
< // 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);