ifdef out ability to feed real-time through simulator
authorCraig Dowell <craigdo@ee.washington.edu>
Tue, 26 Aug 2008 23:11:11 -0700
changeset 3561 e388935fa948
parent 3560 5aa65b1ea001
child 3562 385bdac52fd3
ifdef out ability to feed real-time through simulator
src/simulator/event-impl.h
src/simulator/realtime-simulator-impl.cc
src/simulator/realtime-simulator-impl.h
--- a/src/simulator/event-impl.h	Tue Aug 26 15:34:57 2008 -0700
+++ b/src/simulator/event-impl.h	Tue Aug 26 23:11:11 2008 -0700
@@ -167,7 +167,7 @@
 void
 EventImpl::Unref (void) const
 {
-  register uint32_t c;
+  uint32_t c;
 
   if (m_eventLock)
     {
--- a/src/simulator/realtime-simulator-impl.cc	Tue Aug 26 15:34:57 2008 -0700
+++ b/src/simulator/realtime-simulator-impl.cc	Tue Aug 26 23:11:11 2008 -0700
@@ -47,11 +47,13 @@
   static TypeId tid = TypeId ("ns3::RealtimeSimulatorImpl")
     .SetParent<Object> ()
     .AddConstructor<RealtimeSimulatorImpl> ()
+#ifdef PERMIT_WALLCLOCK_SIMULATION_TIME
     .AddAttribute ("ReportSimulatedTime", 
                    "Report simulated time in Simulator::Now if true, otherwise wall-clock time (will be different).",
                    BooleanValue (true),
                    MakeBooleanAccessor (&RealtimeSimulatorImpl::m_reportSimulatedTime),
                    MakeBooleanChecker ())
+#endif
     .AddAttribute ("SynchronizationMode", 
                    "What to do if the simulation cannot keep up with real time.",
                    EnumValue (SYNC_BEST_EFFORT),
@@ -641,6 +643,7 @@
 Time
 RealtimeSimulatorImpl::Now (void) const
 {
+#ifdef PERMIT_WALLCLOCK_SIMULATION_TIME
   //
   // The behavior of Now depends on the setting of the "ReportSimulatedTime"
   // attribute.  If this is set to true, then Now will pretend that the realtime
@@ -665,19 +668,56 @@
     {
       return TimeStep (m_currentTs);
     }
+#else // Do not PERMIT_WALLCLOCK_SIMULATION_TIME (the normal case)
+  return TimeStep (m_currentTs);
+#endif // Do not PERMIT_WALLCLOCK_SIMULATION_TIME (the normal case)
 }
 
 Time 
 RealtimeSimulatorImpl::GetDelayLeft (const EventId &id) const
 {
+  //
+  // If the event has expired, there is no delay until it runs.  It is not the
+  // case that there is a negative time until it runs.
+  //
   if (IsExpired (id))
     {
       return TimeStep (0);
     }
+
+#ifdef PERMIT_WALLCLOCK_SIMULATION_TIME
+  //
+  // If we're running in real-time mode, it is possible that an event has been
+  // entered into the system using ScheduleNow, which used the current real
+  // time as the invocation time.  By the time the scheduler gets around to
+  // running the event, there will be an implied negative GetDelayLeft.  From
+  // a client point of view, if someone were to ScheduleNow an event and follow
+  // that immediately by a GetDelayLeft on that event there would be a negative 
+  // GetDelayLeft since it is almost certain that at least one minimum time 
+  // quantum has passed.  We don't allow these cases to happen.  GetDelayLeft
+  // reports zero if the event has expired OR if it is late.
+  // 
+  if ((m_reportSimulatedTime == false) && Running ())
+    {
+      uint64_t tsEvent = id.GetTs ();
+      uint64_t tsNow = m_synchronizer->GetCurrentRealtime ();
+
+      if (tsEvent > tsNow)
+        {
+          return TimeStep (tsEvent - tsNow);
+        }
+      else
+        {
+          return TimeStep (0);
+        }
+    }
   else
     {
-      return TimeStep (id.GetTs () - m_synchronizer->GetCurrentRealtime ());
+      return TimeStep (id.GetTs () - m_currentTs);
     }
+#else  // Do not PERMIT_WALLCLOCK_SIMULATION_TIME (the normal case)
+  return TimeStep (id.GetTs () - m_currentTs);
+#endif // Do not PERMIT_WALLCLOCK_SIMULATION_TIME (the normal case)
 }
 
 void
@@ -739,10 +779,18 @@
          }
       return true;
     }
+
+  //
+  // If the time of the event is less than the current timestamp of the 
+  // simulator, the simulator has gone past the invocation time of the 
+  // event, so the statement ev.GetTs () < m_currentTs does mean that 
+  // the event has been fired even in realtime mode.
+  //
+  // The same is true for the next line involving the m_currentUid.
+  //
   if (ev.PeekEventImpl () == 0 ||
       ev.GetTs () < m_currentTs ||
-      (ev.GetTs () == m_currentTs &&
-       ev.GetUid () <= m_currentUid) ||
+      (ev.GetTs () == m_currentTs && ev.GetUid () <= m_currentUid) ||
       ev.PeekEventImpl ()->IsCancelled ()) 
     {
       return true;
@@ -790,5 +838,3 @@
 }
   
 }; // namespace ns3
-
-
--- a/src/simulator/realtime-simulator-impl.h	Tue Aug 26 15:34:57 2008 -0700
+++ b/src/simulator/realtime-simulator-impl.h	Tue Aug 26 23:11:11 2008 -0700
@@ -113,6 +113,8 @@
   RealtimeEventLock m_eventLock;
 
   Ptr<Synchronizer> m_synchronizer;
+
+#ifdef PERMIT_WALLCLOCK_SIMULATION_TIME
   /*
    * In calls to Simulator::Now we have a basic choice to make.  We can either
    * report back the time the simulator thinks it should be, or we can report 
@@ -136,6 +138,7 @@
    * variations in host process scheduling, for example.
    */
   bool m_reportSimulatedTime;
+#endif
 
   /**
    * The policy to use if the simulation cannot keep synchronized to real-time.