mtp: Keep original event UID after automatic partition

This commit is contained in:
F5
2023-11-22 13:17:33 +08:00
parent 2f30ba37c4
commit 26f7c97791
3 changed files with 48 additions and 19 deletions

View File

@@ -113,6 +113,30 @@ MtpInterface::EnableNew(const uint32_t newSystemCount)
{
g_systems[i].Enable(i, g_systemCount + 1);
}
UintegerValue ui;
g_sortPeriod.GetValue(ui);
if (ui.Get() == 0)
{
g_period = std::ceil(std::log2(g_systemCount) / 4 + 1);
NS_LOG_INFO("Secheduling period is automatically set to " << g_period);
}
else
{
g_period = ui.Get();
}
// create a thread local storage key
// so that we can access the currently assigned LP of each thread
pthread_key_create(&g_key, nullptr);
pthread_setspecific(g_key, &g_systems[0]);
}
void
MtpInterface::EnableNew(const uint32_t threadCount, const uint32_t newSystemCount)
{
g_threadCount = threadCount;
EnableNew(newSystemCount);
}
void

View File

@@ -35,6 +35,7 @@ class MtpInterface
static void Enable(const uint32_t threadCount); // auto partition, specify thread count
static void Enable(const uint32_t threadCount, const uint32_t systemCount); // manual partition
static void EnableNew(const uint32_t newSystemCount); // add LPs for dynamic added node
static void EnableNew(const uint32_t threadCount, const uint32_t newSystemCount);
static void Disable();
static void Run();
static void RunBefore();

View File

@@ -141,8 +141,7 @@ MultithreadedSimulatorImpl::Remove(const EventId& id)
if (id.GetUid() == EventId::DESTROY)
{
// destroy events.
for (std::list<EventId>::iterator i = m_destroyEvents.begin(); i != m_destroyEvents.end();
i++)
for (auto i = m_destroyEvents.begin(); i != m_destroyEvents.end(); i++)
{
if (*i == id)
{
@@ -176,9 +175,7 @@ MultithreadedSimulatorImpl::IsExpired(const EventId& id) const
{
return true;
}
for (std::list<EventId>::const_iterator i = m_destroyEvents.begin();
i != m_destroyEvents.end();
i++)
for (auto i = m_destroyEvents.begin(); i != m_destroyEvents.end(); i++)
{
if (*i == id)
{
@@ -206,7 +203,7 @@ MultithreadedSimulatorImpl::Run()
}
Time
MultithreadedSimulatorImpl::Now(void) const
MultithreadedSimulatorImpl::Now() const
{
// Do not add function logging here, to avoid stack overflow
return MtpInterface::GetSystem()->Now();
@@ -226,7 +223,7 @@ MultithreadedSimulatorImpl::GetDelayLeft(const EventId& id) const
}
Time
MultithreadedSimulatorImpl::GetMaximumSimulationTime(void) const
MultithreadedSimulatorImpl::GetMaximumSimulationTime() const
{
return Time::Max() / 2;
}
@@ -243,7 +240,7 @@ MultithreadedSimulatorImpl::SetScheduler(ObjectFactory schedulerFactory)
}
uint32_t
MultithreadedSimulatorImpl::GetSystemId(void) const
MultithreadedSimulatorImpl::GetSystemId() const
{
return MtpInterface::GetSystem()->GetSystemId();
}
@@ -255,7 +252,7 @@ MultithreadedSimulatorImpl::GetContext() const
}
uint64_t
MultithreadedSimulatorImpl::GetEventCount(void) const
MultithreadedSimulatorImpl::GetEventCount() const
{
uint64_t eventCount = 0;
for (uint32_t i = 0; i < MtpInterface::GetSize(); i++)
@@ -284,7 +281,7 @@ MultithreadedSimulatorImpl::Partition()
if (m_minLookahead == TimeStep(0))
{
std::vector<Time> delays;
for (NodeContainer::Iterator it = nodes.Begin(); it != nodes.End(); it++)
for (auto it = nodes.Begin(); it != nodes.End(); it++)
{
Ptr<Node> node = *it;
for (uint32_t i = 0; i < node->GetNDevices(); i++)
@@ -305,7 +302,7 @@ MultithreadedSimulatorImpl::Partition()
}
}
std::sort(delays.begin(), delays.end());
if (delays.size() == 0)
if (delays.empty())
{
m_minLookahead = TimeStep(0);
}
@@ -321,7 +318,7 @@ MultithreadedSimulatorImpl::Partition()
}
// perform a BFS on the whole network topo to assign each node a systemId
for (NodeContainer::Iterator it = nodes.Begin(); it != nodes.End(); it++)
for (auto it = nodes.Begin(); it != nodes.End(); it++)
{
Ptr<Node> node = *it;
if (!visited[node->GetId()])
@@ -380,22 +377,29 @@ MultithreadedSimulatorImpl::Partition()
<< " threads");
// create new LPs
const Ptr<Scheduler> events = MtpInterface::GetSystem()->GetPendingEvents();
MtpInterface::Disable();
MtpInterface::Enable(threadCount, systemCount);
MtpInterface::EnableNew(threadCount, systemCount);
// set scheduler
ObjectFactory schedulerFactory;
schedulerFactory.SetTypeId(m_schedulerTypeId);
for (uint32_t i = 0; i <= systemCount; i++)
for (uint32_t i = 1; i <= systemCount; i++)
{
MtpInterface::GetSystem(i)->SetScheduler(schedulerFactory);
}
// transfer events to new LPs
while (!events->IsEmpty())
// remove old events in public LP
const Ptr<Scheduler> oldEvents = MtpInterface::GetSystem()->GetPendingEvents();
const Ptr<Scheduler> eventsToBeTransferred = schedulerFactory.Create<Scheduler>();
while (!oldEvents->IsEmpty())
{
Scheduler::Event ev = events->RemoveNext();
Scheduler::Event next = oldEvents->RemoveNext();
eventsToBeTransferred->Insert(next);
}
// transfer events to new LPs
while (!eventsToBeTransferred->IsEmpty())
{
Scheduler::Event ev = eventsToBeTransferred->RemoveNext();
// invoke initialization events (at time 0) by their insertion order
// since changing the execution order of these events may cause error,
// they have to be invoked now rather than parallelly executed