[Ns-developers] Proposed Simulator Changes

craigdo@ee.washington.edu craigdo at ee.washington.edu
Mon Oct 13 11:45:05 PDT 2008


[ ... ]

> > > 1) I see that ::RunOneEvent is not implemented in 
> > > RealtimeSimulatorImpl.
> > > Is it not possible to implement it by a single call to 
> > > ProcessOneEvent ?
> > 
> > It can be made to run, but what do you expect it to do?  It 
> certainly
> > isn't
> 
> I expect it to do what it does already, that is, synchronize on the
> wall-clock and execute one event. 

Well, now it (being ns-3-dev) doesn't do anything.  This is what needs to be
clarified.

The wall clock is free-running and completely asynchronous with respect to
the simulation time.  In order to "synchronize on the wall-clock" you need
to establish a relationship between the wall-clock and the simulator clock.
There are a number of things you can do; and the semantics result in very
different behavior and use cases are limited one way or another.

1) When you call RunOneEvent, you can set the origin of the normalized real
time to the time of _last_ event executed (m_currentTs); and then wait for
the time of the _next_ event in the queue.  In this case, you will consume
the real time that would have been executed between the events had the main
event loop been executed.  This removes processing times from something like
the visualizer from the equation, but limits the system to a 1:1
relationship between sim clock and real clock.

2) When you call RunOneEvent, you can synchronize real time with the _next_
event executed (m_currentTs), and wait for the time of the _next_ event in
the queue.  This effectively turns off real-time mode and executes the next
event immediately.  You might as well not even introduce real-time into the
equation.  This would mean RunOneEvent for real-time is basically the
RunOneEvent from the non-real-time case.  This allows something like a
visualizer to completely control the timing (in conjunction with
Simulator::next()) in a simulation but really isn't real-time at all.

3) Provide some additional method to establish the origin of real-time with
respect to simulation time (like Run() does).  When you then subsequently
call RunOneEvent, it will wait for the time of the _next_ event in the
queue.  In this case, you do a real-time simulation but are calling into the
processing loop from the outside; but the "responsibility" for the
real-time-ness is shared between caller and callee.

You privately sent me a patch that just called ProcessOneEvent from
RunOneEvent.  This patch provided no synchronization between real-time clock
and simulation clock -- it apparently relied on the fact that the real-time
clock was running asynchronously and had a huge value most of the time.
This had the effect of making every event "late"; and then caused those
events to be executed immediately.  I think you accidentally implemented
case two.

If you want to add the functionality, you really need to tell me which one
of these cases, or an entirely different one I haven't mentioned, you want
to support, since the user-visible behavior (and responsibilities) may be
quite different.

I think the most flexible thing to do is case two (just make it
non-real-time), but this really doesn't have anything to do with
"synchroniz[ing] on the wall-clock."  What you would gain by making this
feature possible in the real-time simulator would be the multithreaded
behavior and the ability to schedule events from emu or tap devices.  It
would mean that ScheduleRealNow would just effectively be treated as
ScheduleFromAnotherThread.

> This has allowed me to run gustavo's
> visualizer successfully, which, as far as I am concerned, is 
> good-enough
> for now. We can revisit that implementation later if someone complains
> about it.
> 
> > > If you feel that the 'Real' keyword is not
> > > sufficiently-explicit, 'Realtime' or 'WallClock' seem fine:
> > > 
> > > class Simulator 
> > > {
> > > static void ScheduleXXX (Time delay, ...);
> > > static void ScheduleXXXNow (...);
> > > static Time XXXNow (void);
> > > };
> > > 
> > > where XXX is one of Real, Realtime, RealTime, WallClock.
> > 
> > I could be convinced that moving these methods back into Simulator
> > would be
> > okay if we plastered enough warning signs all over them.  If you
> > actually
> 
> Feel free to do so, ?but, please, make sure that no method 
> documentation
> is longer than 3 paragraphs.

Is this some kind of new and undiscussed documentation requirement that you
have unilaterally decided on?  I always thought that documentation should be
sufficient to document the behavior of the function.

> > want to remove the multithread-safety from some simulator 
> methods, and
> > move some multithread-safe methods in, I would say that is a recipe
> > for disaster.
> 
> I obviously am less concerned than you about this potential 
> disaster but
> if you really care about moving these new methods to a 
> separate header,
> I would like to suggest the following which is pretty close 
> to what you
> have right now:
> 
> 0) simulator.h is documented to _not_ be thread-safe.
> 
> 1) wallclock-simulator.h contains WallclockSimulator
> 
> 2) defines:
> class WallclockSimulator 
> {
> static void ScheduleXXX (Time delay, ...);
> static void ScheduleXXXNow (...);
> static Time XXXNow (void);
> };
> 
> 3) WallclockSimulator _API_ is documented to be thread-safe
> 
> 4) implement Simulator and WallclockSimulator in the same file,
> simulator.cc
> 
> 5) extend SimulatorImpl:
> class SimulatorImpl 
> {
>  virtual void ScheduleXXX (Time delay, ...) = 0;
>  virtual void ScheduleXXXNow (...) = 0;
>  virtual Time XXXNow (void) const = 0;
> };
> 
> 6) implement (5) in default-simulator-impl.cc with NS_FATAL_ERROR and
> file a bug about it: we want to eventually implement these correctly.

This sounds reasonable.

Regards,

-- Craig




More information about the Ns-developers mailing list