A Discrete-Event Network Simulator
API
simulator.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 #include "ns3/core-config.h"
21 #include "simulator.h"
22 #include "simulator-impl.h"
23 #include "scheduler.h"
24 #include "map-scheduler.h"
25 #include "event-impl.h"
26 #include "des-metrics.h"
27 
28 #include "ptr.h"
29 #include "string.h"
30 #include "object-factory.h"
31 #include "global-value.h"
32 #include "assert.h"
33 #include "log.h"
34 
35 #include <cmath>
36 #include <fstream>
37 #include <list>
38 #include <vector>
39 #include <iostream>
40 #include <iomanip>
41 
50 namespace ns3 {
51 
52 // Note: Logging in this file is largely avoided due to the
53 // number of calls that are made to these functions and the possibility
54 // of causing recursions leading to stack overflow
55 NS_LOG_COMPONENT_DEFINE ("Simulator");
56 
64  ("SimulatorImplementationType",
65  "The object class to use as the simulator implementation",
66  StringValue ("ns3::DefaultSimulatorImpl"),
68 
75 static GlobalValue g_schedTypeImpl = GlobalValue ("SchedulerType",
76  "The object class to use as the scheduler implementation",
79 
86 static void
87 TimePrinter (std::ostream &os)
88 {
89  std::ios_base::fmtflags ff = os.flags (); // Save stream flags
90  std::streamsize oldPrecision = os.precision ();
91  if (Time::GetResolution () == Time::NS)
92  {
93  os << std::fixed << std::setprecision (9) << Simulator::Now ().As (Time::S);
94  }
95  else if (Time::GetResolution () == Time::PS)
96  {
97  os << std::fixed << std::setprecision (12) << Simulator::Now ().As (Time::S);
98  }
99  else if (Time::GetResolution () == Time::FS)
100  {
101  os << std::fixed << std::setprecision (15) << Simulator::Now ().As (Time::S);
102  }
103  else if (Time::GetResolution () == Time::US)
104  {
105  os << std::fixed << std::setprecision (6) << Simulator::Now ().As (Time::S);
106  }
107  else
108  {
109  // default C++ precision of 5
110  os << std::fixed << std::setprecision (5) << Simulator::Now ().As (Time::S);
111  }
112  os << std::setprecision (oldPrecision);
113  os.flags (ff); // Restore stream flags
114 }
115 
122 static void
123 NodePrinter (std::ostream &os)
124 {
126  {
127  os << "-1";
128  }
129  else
130  {
131  os << Simulator::GetContext ();
132  }
133 }
134 
140 static SimulatorImpl **PeekImpl (void)
141 {
142  static SimulatorImpl *impl = 0;
143  return &impl;
144 }
145 
152 static SimulatorImpl * GetImpl (void)
153 {
154  SimulatorImpl **pimpl = PeekImpl ();
155  /* Please, don't include any calls to logging macros in this function
156  * or pay the price, that is, stack explosions.
157  */
158  if (*pimpl == 0)
159  {
160  {
161  ObjectFactory factory;
162  StringValue s;
163 
164  g_simTypeImpl.GetValue (s);
165  factory.SetTypeId (s.Get ());
166  *pimpl = GetPointer (factory.Create<SimulatorImpl> ());
167  }
168  {
169  ObjectFactory factory;
170  StringValue s;
171  g_schedTypeImpl.GetValue (s);
172  factory.SetTypeId (s.Get ());
173  (*pimpl)->SetScheduler (factory);
174  }
175 
176 //
177 // Note: we call LogSetTimePrinter _after_ creating the implementation
178 // object because the act of creation can trigger calls to the logging
179 // framework which would call the TimePrinter function which would call
180 // Simulator::Now which would call Simulator::GetImpl, and, thus, get us
181 // in an infinite recursion until the stack explodes.
182 //
185  }
186  return *pimpl;
187 }
188 
189 void
191 {
193 
194  SimulatorImpl **pimpl = PeekImpl ();
195  if (*pimpl == 0)
196  {
197  return;
198  }
199  /* Note: we have to call LogSetTimePrinter (0) below because if we do not do
200  * this, and restart a simulation after this call to Destroy, (which is
201  * legal), Simulator::GetImpl will trigger again an infinite recursion until
202  * the stack explodes.
203  */
204  LogSetTimePrinter (0);
205  LogSetNodePrinter (0);
206  (*pimpl)->Destroy ();
207  (*pimpl)->Unref ();
208  *pimpl = 0;
209 }
210 
211 void
213 {
214  NS_LOG_FUNCTION (schedulerFactory);
215  GetImpl ()->SetScheduler (schedulerFactory);
216 }
217 
218 bool
220 {
222  return GetImpl ()->IsFinished ();
223 }
224 
225 void
227 {
230  GetImpl ()->Run ();
231 }
232 
233 void
235 {
237  NS_LOG_LOGIC ("stop");
238  GetImpl ()->Stop ();
239 }
240 
241 void
242 Simulator::Stop (Time const &delay)
243 {
244  NS_LOG_FUNCTION (delay);
245  GetImpl ()->Stop (delay);
246 }
247 
248 Time
250 {
251  /* Please, don't include any calls to logging macros in this function
252  * or pay the price, that is, stack explosions.
253  */
254  return GetImpl ()->Now ();
255 }
256 
257 Time
259 {
260  NS_LOG_FUNCTION (&id);
261  return GetImpl ()->GetDelayLeft (id);
262 }
263 
264 EventId
265 Simulator::Schedule (Time const &delay, const Ptr<EventImpl> &event)
266 {
267  return DoSchedule (delay, GetPointer (event));
268 }
269 
270 EventId
272 {
273  return DoScheduleNow (GetPointer (ev));
274 }
275 void
276 Simulator::ScheduleWithContext (uint32_t context, const Time &delay, EventImpl *impl)
277 {
278 #ifdef ENABLE_DES_METRICS
279  DesMetrics::Get ()->TraceWithContext (context, Now (), delay);
280 #endif
281  return GetImpl ()->ScheduleWithContext (context, delay, impl);
282 }
283 EventId
285 {
286  return DoScheduleDestroy (GetPointer (ev));
287 }
288 EventId
290 {
291 #ifdef ENABLE_DES_METRICS
292  DesMetrics::Get ()->Trace (Now (), time);
293 #endif
294  return GetImpl ()->Schedule (time, impl);
295 }
296 EventId
298 {
299 #ifdef ENABLE_DES_METRICS
300  DesMetrics::Get ()->Trace (Now (), Time (0));
301 #endif
302  return GetImpl ()->ScheduleNow (impl);
303 }
304 EventId
306 {
307  return GetImpl ()->ScheduleDestroy (impl);
308 }
309 
310 
311 EventId
312 Simulator::Schedule (Time const &delay, void (*f)(void))
313 {
314  return DoSchedule (delay, MakeEvent (f));
315 }
316 
317 void
318 Simulator::ScheduleWithContext (uint32_t context, Time const &delay, void (*f)(void))
319 {
320  return ScheduleWithContext (context, delay, MakeEvent (f));
321 }
322 
323 EventId
324 Simulator::ScheduleNow (void (*f)(void))
325 {
326  return DoScheduleNow (MakeEvent (f));
327 }
328 
329 EventId
331 {
332  return DoScheduleDestroy (MakeEvent (f));
333 }
334 
335 void
337 {
338  if (*PeekImpl () == 0)
339  {
340  return;
341  }
342  return GetImpl ()->Remove (id);
343 }
344 
345 void
347 {
348  if (*PeekImpl () == 0)
349  {
350  return;
351  }
352  return GetImpl ()->Cancel (id);
353 }
354 
355 bool
357 {
358  if (*PeekImpl () == 0)
359  {
360  return true;
361  }
362  return GetImpl ()->IsExpired (id);
363 }
364 
365 Time Now (void)
366 {
367  return Time (Simulator::Now ());
368 }
369 
370 Time
372 {
374  return GetImpl ()->GetMaximumSimulationTime ();
375 }
376 
377 uint32_t
379 {
380  return GetImpl ()->GetContext ();
381 }
382 
383 uint32_t
385 {
387 
388  if (*PeekImpl () != 0)
389  {
390  return GetImpl ()->GetSystemId ();
391  }
392  else
393  {
394  return 0;
395  }
396 }
397 
398 void
400 {
401  NS_LOG_FUNCTION (impl);
402  if (*PeekImpl () != 0)
403  {
404  NS_FATAL_ERROR ("It is not possible to set the implementation after calling any Simulator:: function. Call Simulator::SetImplementation earlier or after Simulator::Destroy.");
405  }
406  *PeekImpl () = GetPointer (impl);
407  // Set the default scheduler
408  ObjectFactory factory;
409  StringValue s;
410  g_schedTypeImpl.GetValue (s);
411  factory.SetTypeId (s.Get ());
412  impl->SetScheduler (factory);
413 //
414 // Note: we call LogSetTimePrinter _after_ creating the implementation
415 // object because the act of creation can trigger calls to the logging
416 // framework which would call the TimePrinter function which would call
417 // Simulator::Now which would call Simulator::GetImpl, and, thus, get us
418 // in an infinite recursion until the stack explodes.
419 //
422 }
423 
426 {
428  return GetImpl ();
429 }
430 
431 
432 
433 } // namespace ns3
434 
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:258
Ptr< const AttributeChecker > MakeStringChecker(void)
Definition: string.cc:30
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
std::string Get(void) const
Definition: string.cc:31
ns3::EventImpl declarations.
static void SetImplementation(Ptr< SimulatorImpl > impl)
Definition: simulator.cc:399
virtual bool IsExpired(const EventId &id) const =0
Check if an event has already run or been cancelled.
Hold variables of type string.
Definition: string.h:41
static EventId DoScheduleDestroy(EventImpl *event)
Implementation of the various ScheduleDestroy methods.
Definition: simulator.cc:305
static Ptr< SimulatorImpl > GetImplementation(void)
Get the SimulatorImpl singleton.
Definition: simulator.cc:425
ns3::StringValue attribute value declarations.
ns3::Ptr smart pointer declaration and implementation.
static uint32_t GetSystemId(void)
Get the system id of this simulator.
Definition: simulator.cc:384
virtual Time Now(void) const =0
Return the current simulation virtual time.
static uint32_t GetContext(void)
Get the current simulation context.
Definition: simulator.cc:378
ns3::ObjectFactory class declaration.
static void Run(void)
Run the simulation.
Definition: simulator.cc:226
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
virtual EventId ScheduleNow(EventImpl *event)=0
Schedule an event to run at the current virtual time.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
second
Definition: nstime.h:114
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
Definition: simulator.cc:346
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:719
ns3::Simulator declaration.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
virtual void ScheduleWithContext(uint32_t context, const Time &delay, EventImpl *event)=0
Schedule a future event execution (in a different context).
virtual void SetScheduler(ObjectFactory schedulerFactory)=0
Set the Scheduler to be used to manage the event list.
Hold a so-called 'global value'.
Definition: global-value.h:73
virtual void Cancel(const EventId &id)=0
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
static SimulatorImpl * GetImpl(void)
Get the SimulatorImpl singleton.
Definition: simulator.cc:152
static DesMetrics * Get(void)
Get a pointer to the singleton instance.
ns3::DesMetrics declaration.
virtual void Run(void)=0
Run the simulation.
virtual Time GetMaximumSimulationTime(void) const =0
Get the maximum representable simulation time.
virtual bool IsFinished(void) const =0
Check if the simulation should finish.
virtual void Remove(const EventId &id)=0
Remove an event from the event list.
ns3::SimulatorImpl declaration.
ns3::Scheduler abstract base class, ns3::Scheduler::Event and ns3::Scheduler::EventKey declarations...
U * GetPointer(const Ptr< U > &p)
Definition: ptr.h:570
static EventId Schedule(Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event to expire after delay.
Definition: simulator.h:1375
static enum Unit GetResolution(void)
Definition: time.cc:380
Ptr< Object > Create(void) const
Create an Object instance of the configured TypeId.
void LogSetNodePrinter(LogNodePrinter printer)
Set the LogNodePrinter function to be used to prepend log messages with the node id.
Definition: log.cc:643
NS_ASSERT() and NS_ASSERT_MSG() macro definitions.
virtual Time GetDelayLeft(const EventId &id) const =0
Get the remaining time until this event will execute.
AttributeValue implementation for TypeId.
Definition: type-id.h:608
static SimulatorImpl ** PeekImpl(void)
Get the static SimulatorImpl instance.
Definition: simulator.cc:140
femtosecond
Definition: nstime.h:119
virtual EventId ScheduleDestroy(EventImpl *event)=0
Schedule an event to run at the end of the simulation, after the Stop() time or condition has been re...
static EventId DoSchedule(Time const &delay, EventImpl *event)
Implementation of the various Schedule methods.
Definition: simulator.cc:289
static void NodePrinter(std::ostream &os)
Default node id printer implementation.
Definition: simulator.cc:123
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:190
double f(double x, void *params)
Definition: 80211b.c:72
static void Remove(const EventId &id)
Remove an event from the event list.
Definition: simulator.cc:336
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static bool IsExpired(const EventId &id)
Check if an event has already run or been cancelled.
Definition: simulator.cc:356
void TraceWithContext(uint32_t context, const Time &now, const Time &delay)
Trace an event (with context) at the time it is scheduled.
Definition: des-metrics.cc:105
ns3::GlobalValue declaration.
static void TimePrinter(std::ostream &os)
Default TimePrinter implementation.
Definition: simulator.cc:87
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Schedule an event to expire Now.
Definition: simulator.h:1564
static void SetScheduler(ObjectFactory schedulerFactory)
Set the scheduler type with an ObjectFactory.
Definition: simulator.cc:212
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:249
Flag for events not associated with any particular context.
Definition: simulator.h:192
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
void LogSetTimePrinter(LogTimePrinter printer)
Set the LogTimePrinter function to be used to prepend log messages with the simulation time...
Definition: log.cc:629
microsecond
Definition: nstime.h:116
static GlobalValue g_schedTypeImpl
The specific event scheduler implementation to use.
Definition: simulator.cc:75
Instantiate subclasses of ns3::Object.
static void ScheduleWithContext(uint32_t context, Time const &delay, MEM mem_ptr, OBJ obj)
Schedule an event with the given context.
Definition: simulator.h:1469
A simulation event.
Definition: event-impl.h:44
static EventId DoScheduleNow(EventImpl *event)
Implementation of the various ScheduleNow methods.
Definition: simulator.cc:297
TimeWithUnit As(const enum Unit unit) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:388
virtual EventId Schedule(const Time &delay, EventImpl *event)=0
Schedule a future event execution (in the same context).
An identifier for simulation events.
Definition: event-id.h:53
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:234
virtual void Stop(void)=0
Tell the Simulator the calling event should be the last one executed.
static bool IsFinished(void)
Check if the simulation should finish.
Definition: simulator.cc:219
static EventId ScheduleDestroy(MEM mem_ptr, OBJ obj)
Schedule an event to expire when Simulator::Destroy is called.
Definition: simulator.h:1671
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:365
void Trace(const Time &now, const Time &delay)
Trace an event to self at the time it is scheduled.
Definition: des-metrics.cc:99
picosecond
Definition: nstime.h:118
virtual uint32_t GetSystemId() const =0
Get the system id of this simulator.
nanosecond
Definition: nstime.h:117
ns3::MapScheduler declaration.
static void ClearMarkedTimes()
Remove all MarkedTimes.
Definition: time.cc:256
static GlobalValue g_simTypeImpl
The specific simulator implementation to use.
Definition: simulator.cc:63
Debug message logging.
Ptr< const AttributeChecker > MakeTypeIdChecker(void)
Definition: type-id.cc:1224
virtual uint32_t GetContext(void) const =0
Get the current simulation context.
static Time GetMaximumSimulationTime(void)
Get the maximum representable simulation time.
Definition: simulator.cc:371
The SimulatorImpl base class.
void GetValue(AttributeValue &value) const
Get the value.
EventImpl * MakeEvent(void(*f)(void))
Make an EventImpl from a function pointer taking varying numbers of arguments.
Definition: make-event.cc:34
static TypeId GetTypeId(void)
Register this type.