[Ns-developers] NS-3 GUI (visualization again)
Gustavo Carneiro
gjcarneiro at gmail.com
Wed Jul 30 04:25:19 PDT 2008
2008/7/30 <craigdo at ee.washington.edu>
> [ ... ]
>
> > > RunOne what? RunOne when? In what context?
> >
> > Run one event from the event queue and return immediately. Gustavo
> > suggested adding a bool return value to return whether or not further
> > events are left in the queue. A trivial sample implementation:
> >
> > bool
> > DefaultSimulatorImpl::RunOne (void)
> > {
> > if (!m_events->IsEmpty ())
> > {
> > ProcessOneEvent ();
> > }
> >
> > NS_ASSERT(!m_events->IsEmpty () || m_unscheduledEvents == 0);
> >
> > return !m_events->IsEmpty ();
> > }
> >
> >
> > I thought that the context in which this function would be
> > used would be
> > obvious: it could be used to move the mainloop from ns3 to the
> > application to allow the application to decide when and how to execute
> > events.
>
> Well, not obvious to me, but I haven't been having this conversation with
> Gustavo and I'm coming from an entirely different place. In any case, now
> I
> can answer your question about emu.
>
> This approach is funamentally incompatible with a realtime scheduler unless
> you want to move basically the whole multithreaded interruptible-wait
> realtime-synchronizer thing up into the GUI application. Realtime GUI.
> Yeah-baby :-)
>
> But it does represent something that can be optional and implemented
> differently in different simulator implementations. In the default
> simulator implementation, it makes sense to do something as you show above.
> In a realtime scheduler, it would be implemented as,
>
> bool
> DefaultSimulatorImpl::RunOne (void)
> {
> NS_ASSERT_MSG(false, "No, you really don't want to do that");
> return false;
> }
>
>
I thought you said there is a single simulation thread that dispatches
events, although multiple threads can schedule events. Presumably
(guessing) the simulation thread is the one that calls Simulator::Run. In
that case, wouldn't it make sense to allow multiple RunOne calls to replace
a single Run call? Something like:
void MySimulatorRun ()
{
while (!Simulator::IsFinished ())
{
Simulator::Lock ();
Simulator::RunOne ();
Simulator::UnLock ();
}
}
I would expect the above to work and make sense even for the threaded
simulator. It's all about documentation. No need to assert in
Simulator::RunOne, just put in the documentation that you must hold the
simulator lock before calling it.
Back to my GUI problem, the naive approach that I had in mind was:
Mutext g_myMutex;
void MySimulatorRun ()
{
while (!Simulator::IsFinished ())
{
g_myMutex.Lock ();
Simulator::RunOne ();
g_myMutex.Unlock ();
}
}
// called every 100ms or so
void GuiUpdateTimeout ()
{
g_myMutex.Lock ();
// collect data, update display
g_myMutex.Unlock ();
}
Now, the above approach is kind of naive because it does a lock/unlock pair
for _every event_, which is bound to have some performance implication. A
more clever approach is to unlock-then-lock only once out of N events. N
should be selected such that lock/unlock is done only about once every ~
10ms. The hard part is to figure out what is the correct N for that. I
think it depends on the simulation, and N cannot even be constant, so it has
to be discovered adaptively, by measuring elapsed time for any previous N
iterations and adjusting N accordingly.
--
Gustavo J. A. M. Carneiro
INESC Porto, Telecommunications and Multimedia Unit
"The universe is always one step beyond logic." -- Frank Herbert
More information about the Ns-developers
mailing list