Bug 376 - Mixing use of realtime simulator Schedule and Schedule now problematic
: Mixing use of realtime simulator Schedule and Schedule now problematic
Status: RESOLVED FIXED
: ns-3
simulation core
: ns-3-dev
: All All
: P3 normal
Assigned To:
:
:
:
:
  Show dependency treegraph
 
Reported: 2008-10-08 15:29 EDT by
Modified: 2008-10-27 08:20 EDT (History)


Attachments
Separate out simulator methods that can change time based on realtime clock. (63.98 KB, patch)
2008-10-11 00:12 EDT, Craig Dowell
Details | Diff


Note

You need to log in before you can comment on or make changes to this bug.


Description From 2008-10-08 15:29:29 EDT
Consider the following scenario (not using underlying real time clocks):

  Event A starts running at tA
  Schedule Event B for tA + tEpsilon
  long processing step tP consumes real-time tP
  ScheduleNow Event C

This would result in the following sequence of events:

  Event A, Event C, Event B

If you use ScheduleNow with an underlying realtime clock, and the time consumed
by the the procesing step is small (tP < tEpsilon), the order of execution is
unchanged.  However, if tP > tEpsilon the executed event order changes to

  Event A, Event B, Event C

In the real world tP may vary around tEpsilon and the event ordering may change
unpredictably and incorrectly as system loads vary.

There are cases where doing a ScheduleNow using the actual underlying realtime
clock is required (to cause simulation time to advance in the presence of
external events such as network packet reception).

There are cases where using the underlying realtime clock can cause errors in
situations where dependent events can change order.

The current realtime simulator makes no distinction between scheduling
operations that involve the realtime clock and those that don't.  This leads to
slippery situations.

There need to be two kinds of scheduling methods:  one set that respects time
as models may assume using m_currentTs as a basis, and one set that works with
the current realtime as a basis.  How this works is tricky.  The time to
process event A can no longer affect the order of the events A, B and C.  

If we implement a separate {Schedule, ScheduleNow} and {ScheduleReal,
ScheduleRealNow} the situation changes.  The related events {A,B,C} use
Schedule and ScheduleNow and are therefore using m_currentTs as a basis.  The
external device uses ScheduleRealNow and uses the current realtime as a basis.

What we have then is an unrelated external event being scheduled for some time
during the actual execution of the related events:

  Event A starts running at m_currentTs = tA, realtime ~ tA 
  Schedule() Event B for absolute time tA + tEpsilon (based on m_currentTs)
  long processing step consumes real-time during event A execution
  Packet Reception queues event D for realtime tA < tR < tEpsilon
  ScheduleNow Event C (based on m_currentTs) = tA

Here's what happens:

  1. Event A is run at about realtime = tA.
  2. Event B is inserted at the head of the queue for tA + tEpsilon
     at about realtime tA
  3. Event A continues running for some time tP.  Somewhere during the 
     event, an external thread schedules an event for 
     tA + tR (at the current realtime then) which is less than 
     tA + tEpsilon, so this goes at the head of the event queue.
  4. Event C is scheduled for m_currentTs = tA and so this goes
     to the head of the event queue.

  Event execution is as follows,

  Event A @ tA executes at realtime ~ tA
  Event C @ tA executes at realtime ~ tA plus tP (after event A)
  Event D @ tA + tR executes at realtime tA + tR
  Event B @ tA + tEpsilon

The order of the events A, B, C is preserved.  Event D is an unrelated
"asynchronous" event that happens at some realtime before tA + tEpsilon

You can see that if tA + tR > tA + tEpsilon (the reception event happens during
the execution time of tA (where m_currentTs = tA) but at a realtime > tA +
tEpsilon, the execution order of all events changes, but the ordering of the
events scheduled by Schedule() and ScheduleNow() is preserved.

  Event A @ tA executes at realtime ~ tA
  Event C @ tA executes at realtime ~ tA plus tP (after event A)
  Event B @ tA + tEpsilon
  Event D @ tA + tR executes at realtime tA + tR

This seems to me to be the right thing to do.
------- Comment #1 From 2008-10-10 04:02:51 EDT -------
I would like to see a single ScheduleReal instead of
ScheduleReal+ScheduleRealNow: ScheduleRealNow is purely syntactical sugar for
ScheduleReal(Seconds (0.0)) and I can't imagine that we will have enough users
of this piece of code to make this syntactical sugar very useful.
------- Comment #2 From 2008-10-10 15:16:07 EDT -------
Not that it is a terribly big deal, but I think the two models, real and
non-real, should be symmetric.

I think the main use for the real-time call will be in the form of
ScheduleRealNow(); and I think forcing the user (probably mostly me) to always
call ScheduleReal(0) is just unnecessary obfuscation.

I like syntactic sugar, since its purpose is to make my life easier.  I like
symmetrical interfaces since it means fewer exceptions to remember.
------- Comment #3 From 2008-10-11 00:12:48 EDT -------
Created an attachment (id=264) [details]
Separate out simulator methods that can change time based on realtime clock.