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); 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 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); // auto partition, specify thread count
static void Enable(const uint32_t threadCount, const uint32_t systemCount); // manual partition 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 newSystemCount); // add LPs for dynamic added node
static void EnableNew(const uint32_t threadCount, const uint32_t newSystemCount);
static void Disable(); static void Disable();
static void Run(); static void Run();
static void RunBefore(); static void RunBefore();

View File

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