x86: Track message based interrupt cleanup functions in sender state.
authorGabe Black <gabeblack@google.com>
Wed, 4 Mar 2020 00:28:19 +0000 (16:28 -0800)
committerGabe Black <gabeblack@google.com>
Wed, 4 Mar 2020 09:10:38 +0000 (09:10 +0000)
This makes sure the completion function follows the packet, and allows
multiple packets to be in flight at once without the functions
overwritting each other.

Change-Id: Ic49c7b646d56b32c0453931942ee22ae07828bb6
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/26163
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Reviewed-by: Ayaz Akram <yazakram@ucdavis.edu>
Maintainer: Jason Lowe-Power <jason@lowepower.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/dev/x86/intdev.hh

index a40a1d4f54623422134053e3eb11c2514a172ef8..a681a2e22c1c7baec65348d40d0c1da68fd29c16 100644 (file)
@@ -45,6 +45,7 @@
 #include <functional>
 #include <string>
 
+#include "base/cast.hh"
 #include "mem/tport.hh"
 #include "sim/sim_object.hh"
 
@@ -103,7 +104,11 @@ class IntMasterPort : public QueuedMasterPort
     Tick latency;
 
     typedef std::function<void(PacketPtr)> OnCompletionFunc;
-    OnCompletionFunc onCompletion = nullptr;
+    struct OnCompletion : public Packet::SenderState
+    {
+        OnCompletionFunc func;
+        OnCompletion(OnCompletionFunc _func) : func(_func) {}
+    };
     // If nothing extra needs to happen, just clean up the packet.
     static void defaultOnCompletion(PacketPtr pkt) { delete pkt; }
 
@@ -120,8 +125,9 @@ class IntMasterPort : public QueuedMasterPort
     recvTimingResp(PacketPtr pkt) override
     {
         assert(pkt->isResponse());
-        onCompletion(pkt);
-        onCompletion = nullptr;
+        auto *oc = safe_cast<OnCompletion *>(pkt->popSenderState());
+        oc->func(pkt);
+        delete oc;
         return true;
     }
 
@@ -130,7 +136,7 @@ class IntMasterPort : public QueuedMasterPort
             OnCompletionFunc func=defaultOnCompletion)
     {
         if (timing) {
-            onCompletion = func;
+            pkt->pushSenderState(new OnCompletion(func));
             schedTimingReq(pkt, curTick() + latency);
             // The target handles cleaning up the packet in timing mode.
         } else {