2008-09-21 13:10:08 -07:00
|
|
|
@node RealTime
|
|
|
|
|
@chapter Real-Time Scheduler
|
|
|
|
|
@anchor{chap:RealTime}
|
|
|
|
|
|
|
|
|
|
ns-3 has been designed for integration into testbed and virtual machine
|
|
|
|
|
environments. To integrate with real network stacks and emit/consume
|
|
|
|
|
packets, a real-time scheduler is needed to try to lock the simulation
|
|
|
|
|
clock with the hardware clock. We describe here a component of this:
|
|
|
|
|
the RealTime scheduler.
|
|
|
|
|
|
|
|
|
|
The purpose of the realtime scheduler is to cause the progression of
|
|
|
|
|
the simulation clock to occur synchronously with respect to some
|
|
|
|
|
external time base. Without the presence of an external time base
|
|
|
|
|
(wall clock), simulation time jumps instantly from one simulated time to
|
|
|
|
|
the next.
|
|
|
|
|
|
|
|
|
|
@section Behavior
|
|
|
|
|
|
|
|
|
|
When using a non-realtime scheduler (the default in ns-3), the simulator
|
|
|
|
|
advances the simulation time to the next scheduled event. During event
|
|
|
|
|
execution, simulation time is frozen. With the realtime scheduler, the
|
|
|
|
|
behavior is similar from the perspective of simulation models (i.e.,
|
|
|
|
|
simulation time is frozen during event execution), but between events,
|
|
|
|
|
the simulator will attempt to keep the simulation clock aligned with
|
|
|
|
|
the machine clock.
|
|
|
|
|
|
|
|
|
|
When an event is finished executing, and the scheduler moves to the next
|
|
|
|
|
event, the scheduler compares the next event execution time with the
|
|
|
|
|
machine clock. If the next event is scheduled for a future time,
|
|
|
|
|
the simulator sleeps until that realtime is reached and then executes
|
|
|
|
|
the next event.
|
|
|
|
|
|
|
|
|
|
It may happen that, due to the processing inherent in the execution
|
|
|
|
|
of simulation events, that the simulator cannot keep up with realtime.
|
|
|
|
|
In such a case, it is up to the user configuration what to do. There
|
|
|
|
|
are two ns-3 attributes that govern the behavior. The first is
|
|
|
|
|
@code{ns3::RealTimeSimulatorImpl::SynchronizationMode}. The two
|
|
|
|
|
entries possible for this attribute are @code{BestEffort} (the default)
|
|
|
|
|
or @code{HardLimit}. In "BestEffort" mode, the simulator will just
|
|
|
|
|
try to catch up to realtime by executing events until it reaches
|
|
|
|
|
a point where the next event is in the (realtime) future, or else
|
|
|
|
|
the simulation ends. In BestEffort mode, then, it is possible for
|
|
|
|
|
the simulation to consume more time than the wall clock time. The
|
|
|
|
|
other option "HardLimit" will cause the simulation to abort if the tolerance
|
|
|
|
|
threshold is exceeded. This attribute is
|
|
|
|
|
@code{ns3::RealTimeSimulatorImpl::HardLimit} and the default is 0.1 seconds.
|
|
|
|
|
|
|
|
|
|
A different mode of operation is one in which simulated time is @strong{not}
|
|
|
|
|
frozen during an event execution. This mode of realtime simulation was
|
|
|
|
|
implemented but removed from the ns-3 tree because of questions of whether
|
|
|
|
|
it would be useful. If users are interested in a realtime simulator
|
|
|
|
|
for which simulation time does not freeze during event execution (i.e.,
|
|
|
|
|
every call to @code{Simulator::Now()} returns the current wall clock time,
|
|
|
|
|
not the time at which the event started executing), please contact the
|
|
|
|
|
ns-developers mailing list.
|
|
|
|
|
|
|
|
|
|
@section Usage
|
|
|
|
|
|
|
|
|
|
The usage of the realtime simulator is straightforward, from a scripting
|
|
|
|
|
perspective. Users just need to set the attribute
|
|
|
|
|
@code{SimulatorImplementationType} to the Realtime simulator, such as follows:
|
|
|
|
|
@verbatim
|
|
|
|
|
GlobalValue::Bind ("SimulatorImplementationType",
|
|
|
|
|
StringValue ("ns3::RealtimeSimulatorImpl"));
|
|
|
|
|
@end verbatim
|
|
|
|
|
|
|
|
|
|
There is a script in @code{examples/realtime-udp-echo.cc} that has an
|
|
|
|
|
example of how to configure the realtime behavior. Try:
|
|
|
|
|
@verbatim
|
|
|
|
|
./waf --run realtime-udp-echo
|
|
|
|
|
@end verbatim
|
|
|
|
|
|
|
|
|
|
Whether the simulator will work in a best effort or hard limit policy
|
|
|
|
|
fashion is governed by the attributes explained in the previous section.
|
|
|
|
|
|
|
|
|
|
@section Implementation
|
|
|
|
|
|
|
|
|
|
The implementation is contained in the following files:
|
|
|
|
|
@itemize @bullet
|
2009-04-25 14:56:52 -07:00
|
|
|
@item @code{src/simulator/realtime-simulator-impl.@{cc,h@}}
|
|
|
|
|
@item @code{src/simulator/wall-clock-synchronizer.@{cc,h@}}
|
2008-09-21 13:10:08 -07:00
|
|
|
@end itemize
|
|
|
|
|
|
|
|
|
|
In order to create a realtime scheduler, to a first approximation you
|
|
|
|
|
just want to cause simulation time jumps to consume real time. We propose
|
|
|
|
|
doing this using a combination of sleep- and busy- waits. Sleep-waits cause
|
|
|
|
|
the calling process (thread) to yield the processor for some amount of time.
|
|
|
|
|
Even though this specified amount of time can be passed to nanosecond
|
|
|
|
|
resolution, it is actually converted to an OS-specific granularity.
|
|
|
|
|
In Linux, the granularity is called a Jiffy. Typically this resolution is
|
|
|
|
|
insufficient for our needs (on the order of a ten milliseconds), so we
|
|
|
|
|
round down and sleep for some smaller number of Jiffies. The process is
|
|
|
|
|
then awakened after the specified number of Jiffies has passed. At this
|
|
|
|
|
time, we have some residual time to wait. This time is generally smaller
|
|
|
|
|
than the minimum sleep time, so we busy-wait for the remainder of the time.
|
|
|
|
|
This means that the thread just sits in a for loop consuming cycles until
|
|
|
|
|
the desired time arrives. After the combination of sleep- and busy-waits,
|
|
|
|
|
the elapsed realtime (wall) clock should agree with the simulation time
|
|
|
|
|
of the next event and the simulation proceeds.
|
|
|
|
|
|