Simplify manageResponses, segmentation fault for large transactions!

This commit is contained in:
Lukas Steiner
2022-05-10 14:08:31 +02:00
parent e9942d5aa2
commit 9293a48717
5 changed files with 58 additions and 116 deletions

View File

@@ -145,7 +145,7 @@ void TlmRecorder::recordPhase(tlm_generic_payload& trans, const tlm_phase& phase
tlm_generic_payload* keyTrans;
if (ChildExtension::isChildTrans(trans))
{
keyTrans = &trans.get_extension<ChildExtension>()->getParentTrans();
keyTrans = &ChildExtension::getParentTrans(trans);
}
else
{
@@ -230,7 +230,7 @@ void TlmRecorder::removeTransactionFromSystem(tlm_generic_payload &trans)
PRINTDEBUGMESSAGE(name, "Removing transaction #" +
std::to_string(currentTransactionsInSystem.at(&trans).id));
Transaction &recordingData = currentTransactionsInSystem.at(&trans);
Transaction& recordingData = currentTransactionsInSystem.at(&trans);
currentDataBuffer->push_back(recordingData);
currentTransactionsInSystem.erase(&trans);

View File

@@ -89,6 +89,7 @@ private:
struct Transaction
{
Transaction(const Transaction& other) = default;
Transaction(uint64_t id, uint64_t address, unsigned int dataLength, char cmd,
const sc_core::sc_time& timeOfGeneration, Thread thread, Channel channel) :
id(id), address(address), dataLength(dataLength), cmd(cmd), timeOfGeneration(timeOfGeneration),
@@ -154,7 +155,7 @@ private:
std::vector<Transaction> *storageDataBuffer;
std::thread storageThread;
std::unordered_map<tlm::tlm_generic_payload *, Transaction> currentTransactionsInSystem;
std::unordered_map<tlm::tlm_generic_payload*, Transaction> currentTransactionsInSystem;
uint64_t totalNumTransactions;
sc_core::sc_time simulationTimeCoveredByRecording;

View File

@@ -378,6 +378,11 @@ tlm::tlm_generic_payload& ChildExtension::getParentTrans()
return *parentTrans;
}
tlm::tlm_generic_payload& ChildExtension::getParentTrans(tlm::tlm_generic_payload& childTrans)
{
return childTrans.get_extension<ChildExtension>()->getParentTrans();
}
void ChildExtension::setExtension(tlm::tlm_generic_payload& childTrans, tlm::tlm_generic_payload& parentTrans)
{
auto* extension = childTrans.get_extension<ChildExtension>();
@@ -401,11 +406,6 @@ bool ChildExtension::isChildTrans(const tlm::tlm_generic_payload& trans)
return false;
}
bool ChildExtension::notifyChildTransCompletion()
{
return parentTrans->get_extension<ParentExtension>()->notifyChildTransCompletion();
}
tlm_extension_base* ParentExtension::clone() const
{
return new ParentExtension(childTranses);
@@ -417,15 +417,6 @@ void ParentExtension::copy_from(const tlm_extension_base& ext)
childTranses = cpyFrom.childTranses;
}
bool ParentExtension::isParentTrans(const tlm::tlm_generic_payload& trans)
{
auto* extension = trans.get_extension<ParentExtension>();
if (extension != nullptr)
return !extension->childTranses.empty();
else
return false;
}
void ParentExtension::setExtension(tlm::tlm_generic_payload& parentTrans, std::vector<tlm::tlm_generic_payload*> childTranses)
{
auto* extension = parentTrans.get_extension<ParentExtension>();
@@ -433,7 +424,6 @@ void ParentExtension::setExtension(tlm::tlm_generic_payload& parentTrans, std::v
if (extension != nullptr)
{
extension->childTranses = std::move(childTranses);
extension->nextEndReqChildId = 0;
extension->completedChildTranses = 0;
}
else
@@ -451,12 +441,20 @@ const std::vector<tlm::tlm_generic_payload*>& ParentExtension::getChildTranses()
bool ParentExtension::notifyChildTransCompletion()
{
completedChildTranses++;
return completedChildTranses == childTranses.size();
if (completedChildTranses == childTranses.size())
{
std::for_each(childTranses.begin(), childTranses.end(),
[](tlm::tlm_generic_payload* childTrans){childTrans->release();});
childTranses.clear();
return true;
}
else
{
return false;
}
}
void ParentExtension::releaseChildTranses()
bool ParentExtension::notifyChildTransCompletion(tlm::tlm_generic_payload& trans)
{
std::for_each(childTranses.begin(), childTranses.end(),
[](tlm::tlm_generic_payload* childTrans){childTrans->release();});
childTranses.clear();
}
return trans.get_extension<ParentExtension>()->notifyChildTransCompletion();
}

View File

@@ -264,16 +264,15 @@ public:
tlm::tlm_extension_base* clone() const override;
void copy_from(const tlm::tlm_extension_base& ext) override;
tlm::tlm_generic_payload& getParentTrans();
static tlm::tlm_generic_payload& getParentTrans(tlm::tlm_generic_payload& childTrans);
static void setExtension(tlm::tlm_generic_payload& childTrans, tlm::tlm_generic_payload& parentTrans);
static bool isChildTrans(const tlm::tlm_generic_payload& trans);
bool notifyChildTransCompletion();
};
class ParentExtension : public tlm::tlm_extension<ParentExtension>
{
private:
std::vector<tlm::tlm_generic_payload*> childTranses;
unsigned nextEndReqChildId = 0;
unsigned completedChildTranses = 0;
explicit ParentExtension(std::vector<tlm::tlm_generic_payload*> _childTranses)
: childTranses(std::move(_childTranses)) {}
@@ -283,11 +282,10 @@ public:
tlm_extension_base* clone() const override;
void copy_from(const tlm_extension_base& ext) override;
static bool isParentTrans(const tlm::tlm_generic_payload& trans);
static void setExtension(tlm::tlm_generic_payload& parentTrans, std::vector<tlm::tlm_generic_payload*> childTranses);
const std::vector<tlm::tlm_generic_payload*>& getChildTranses();
bool notifyChildTransCompletion();
void releaseChildTranses();
static bool notifyChildTransCompletion(tlm::tlm_generic_payload& trans);
};
#endif // DRAMEXTENSIONS_H

View File

@@ -477,104 +477,30 @@ void Controller::manageResponses()
if (transToRelease.payload != nullptr)
{
assert(transToRelease.time >= sc_time_stamp());
if (transToRelease.time == sc_time_stamp())
if (transToRelease.time == sc_time_stamp()) // END_RESP completed
{
NDEBUG_UNUSED(uint64_t id) = ControllerExtension::getChannelPayloadID(*transToRelease.payload);
PRINTDEBUGMESSAGE(name(), "Payload " + std::to_string(id) + " left system.");
numberOfBeatsServed += ControllerExtension::getBurstLength(*transToRelease.payload);
transToRelease.payload->release();
transToRelease.payload = nullptr;
totalNumberOfPayloads--; // Important!! has to be done once for parent transaction
totalNumberOfPayloads--;
if (totalNumberOfPayloads == 0)
{
idleTimeCollector.start();
}
else
{
// TODO: hier fehlt noch was
tlm_generic_payload* nextPayloadInQueue = respQueue->nextPayload();
//transToRelease.payload = respQueue->nextPayload();
if (nextPayloadInQueue != nullptr)
{
if (ChildExtension::isChildTrans(*nextPayloadInQueue))
{
tlm_generic_payload& parentTrans = nextPayloadInQueue->get_extension<ChildExtension>()->getParentTrans();
bool allChildTransesCompleted = parentTrans.get_extension<ParentExtension>()->notifyChildTransCompletion();
if (allChildTransesCompleted)
{
parentTrans.get_extension<ParentExtension>()->releaseChildTranses();
transToRelease.payload = &parentTrans;
// last payload was released in this cycle
tlm_phase bwPhase = BEGIN_RESP;
sc_time bwDelay = memSpec.tCK;
sendToFrontend(*transToRelease.payload, bwPhase, bwDelay);
transToRelease.time = sc_max_time();
}
else
{
sc_time triggerTime = respQueue->getTriggerTime();
if (triggerTime != sc_max_time())
dataResponseEvent.notify(triggerTime - sc_time_stamp());
}
}
else
{
transToRelease.payload = nextPayloadInQueue;
// last payload was released in this cycle
tlm_phase bwPhase = BEGIN_RESP;
sc_time bwDelay = memSpec.tCK;
sendToFrontend(*transToRelease.payload, bwPhase, bwDelay);
transToRelease.time = sc_max_time();
}
}
else
{
sc_time triggerTime = respQueue->getTriggerTime();
if (triggerTime != sc_max_time())
dataResponseEvent.notify(triggerTime - sc_time_stamp());
}
}
}
}
else
tlm_generic_payload* nextPayloadInRespQueue = respQueue->nextPayload();
if (nextPayloadInRespQueue != nullptr)
{
tlm_generic_payload* nextPayloadInQueue = respQueue->nextPayload();
if (nextPayloadInQueue != nullptr)
numberOfBeatsServed += ControllerExtension::getBurstLength(*nextPayloadInRespQueue);
if (ChildExtension::isChildTrans(*nextPayloadInRespQueue))
{
if (ChildExtension::isChildTrans(*nextPayloadInQueue))
tlm_generic_payload& parentTrans = ChildExtension::getParentTrans(*nextPayloadInRespQueue);
if (ParentExtension::notifyChildTransCompletion(parentTrans))
{
tlm_generic_payload& parentTrans = nextPayloadInQueue->get_extension<ChildExtension>()->getParentTrans();
bool allChildTransesCompleted = parentTrans.get_extension<ParentExtension>()->notifyChildTransCompletion();
if (allChildTransesCompleted)
{
parentTrans.get_extension<ParentExtension>()->releaseChildTranses();
transToRelease.payload = &parentTrans;
// last payload was released in this cycle
tlm_phase bwPhase = BEGIN_RESP;
sc_time bwDelay;
if (transToRelease.time == sc_time_stamp()) // last payload was released in this cycle
bwDelay = memSpec.tCK;
else
bwDelay = SC_ZERO_TIME;
sendToFrontend(*transToRelease.payload, bwPhase, bwDelay);
transToRelease.time = sc_max_time();
}
else
{
sc_time triggerTime = respQueue->getTriggerTime();
if (triggerTime != sc_max_time())
dataResponseEvent.notify(triggerTime - sc_time_stamp());
}
}
else
{
transToRelease.payload = nextPayloadInQueue;
// last payload was released in this cycle
transToRelease.payload = &parentTrans;
tlm_phase bwPhase = BEGIN_RESP;
sc_time bwDelay;
if (transToRelease.time == sc_time_stamp()) // last payload was released in this cycle
@@ -585,14 +511,33 @@ void Controller::manageResponses()
sendToFrontend(*transToRelease.payload, bwPhase, bwDelay);
transToRelease.time = sc_max_time();
}
else
{
sc_time triggerTime = respQueue->getTriggerTime();
if (triggerTime != sc_max_time())
dataResponseEvent.notify(triggerTime - sc_time_stamp());
}
}
else
{
sc_time triggerTime = respQueue->getTriggerTime();
if (triggerTime != sc_max_time())
dataResponseEvent.notify(triggerTime - sc_time_stamp());
transToRelease.payload = nextPayloadInRespQueue;
tlm_phase bwPhase = BEGIN_RESP;
sc_time bwDelay;
if (transToRelease.time == sc_time_stamp()) // last payload was released in this cycle
bwDelay = memSpec.tCK;
else
bwDelay = SC_ZERO_TIME;
sendToFrontend(*transToRelease.payload, bwPhase, bwDelay);
transToRelease.time = sc_max_time();
}
}
else
{
sc_time triggerTime = respQueue->getTriggerTime();
if (triggerTime != sc_max_time())
dataResponseEvent.notify(triggerTime - sc_time_stamp());
}
}
void Controller::sendToFrontend(tlm_generic_payload& payload, tlm_phase& phase, sc_time& delay)