Simplify manageResponses, segmentation fault for large transactions!
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user