x86: Track message based interrupt cleanup functions in sender state.

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>
This commit is contained in:
Gabe Black
2020-03-03 16:28:19 -08:00
parent ebd62eff3c
commit de24aafc16

View 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 {