A Discrete-Event Network Simulator
API
simulator.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2005,2006 INRIA
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18  */
19 #include "simulator.h"
20 
21 #include "assert.h"
22 #include "des-metrics.h"
23 #include "event-impl.h"
24 #include "global-value.h"
25 #include "log.h"
26 #include "map-scheduler.h"
27 #include "object-factory.h"
28 #include "ptr.h"
29 #include "scheduler.h"
30 #include "simulator-impl.h"
31 #include "string.h"
32 
33 #include "ns3/core-config.h"
34 
35 #include <cmath>
36 #include <fstream>
37 #include <iomanip>
38 #include <iostream>
39 #include <list>
40 #include <vector>
41 
49 namespace ns3
50 {
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 
65  GlobalValue("SimulatorImplementationType",
66  "The object class to use as the simulator implementation",
67  StringValue("ns3::DefaultSimulatorImpl"),
69 
78  GlobalValue("SchedulerType",
79  "The object class to use as the scheduler implementation",
82 
88 static SimulatorImpl**
90 {
91  static SimulatorImpl* impl = nullptr;
92  return &impl;
93 }
94 
101 static SimulatorImpl*
103 {
104  SimulatorImpl** pimpl = PeekImpl();
105  /* Please, don't include any calls to logging macros in this function
106  * or pay the price, that is, stack explosions.
107  */
108  if (*pimpl == nullptr)
109  {
110  {
111  ObjectFactory factory;
112  StringValue s;
113 
115  factory.SetTypeId(s.Get());
116  *pimpl = GetPointer(factory.Create<SimulatorImpl>());
117  }
118  {
119  ObjectFactory factory;
120  StringValue s;
122  factory.SetTypeId(s.Get());
123  (*pimpl)->SetScheduler(factory);
124  }
125 
126  //
127  // Note: we call LogSetTimePrinter _after_ creating the implementation
128  // object because the act of creation can trigger calls to the logging
129  // framework which would call the TimePrinter function which would call
130  // Simulator::Now which would call Simulator::GetImpl, and, thus, get us
131  // in an infinite recursion until the stack explodes.
132  //
135  }
136  return *pimpl;
137 }
138 
139 void
141 {
143 
144  SimulatorImpl** pimpl = PeekImpl();
145  if (*pimpl == nullptr)
146  {
147  return;
148  }
149  /* Note: we have to call LogSetTimePrinter (0) below because if we do not do
150  * this, and restart a simulation after this call to Destroy, (which is
151  * legal), Simulator::GetImpl will trigger again an infinite recursion until
152  * the stack explodes.
153  */
154  LogSetTimePrinter(nullptr);
155  LogSetNodePrinter(nullptr);
156  (*pimpl)->Destroy();
157  (*pimpl)->Unref();
158  *pimpl = nullptr;
159 }
160 
161 void
163 {
164  NS_LOG_FUNCTION(schedulerFactory);
165  GetImpl()->SetScheduler(schedulerFactory);
166 }
167 
168 bool
170 {
172  return GetImpl()->IsFinished();
173 }
174 
175 void
177 {
180  GetImpl()->Run();
181 }
182 
183 void
185 {
187  NS_LOG_LOGIC("stop");
188  GetImpl()->Stop();
189 }
190 
191 void
192 Simulator::Stop(const Time& delay)
193 {
194  NS_LOG_FUNCTION(delay);
195  GetImpl()->Stop(delay);
196 }
197 
198 Time
200 {
201  /* Please, don't include any calls to logging macros in this function
202  * or pay the price, that is, stack explosions.
203  */
204  return GetImpl()->Now();
205 }
206 
207 Time
209 {
210  NS_LOG_FUNCTION(&id);
211  return GetImpl()->GetDelayLeft(id);
212 }
213 
214 EventId
215 Simulator::Schedule(const Time& delay, const Ptr<EventImpl>& event)
216 {
217  return DoSchedule(delay, GetPointer(event));
218 }
219 
220 EventId
222 {
223  return DoScheduleNow(GetPointer(ev));
224 }
225 
226 void
227 Simulator::ScheduleWithContext(uint32_t context, const Time& delay, EventImpl* impl)
228 {
229 #ifdef ENABLE_DES_METRICS
230  DesMetrics::Get()->TraceWithContext(context, Now(), delay);
231 #endif
232  return GetImpl()->ScheduleWithContext(context, delay, impl);
233 }
234 
235 EventId
237 {
238  return DoScheduleDestroy(GetPointer(ev));
239 }
240 
241 EventId
243 {
244 #ifdef ENABLE_DES_METRICS
245  DesMetrics::Get()->Trace(Now(), time);
246 #endif
247  return GetImpl()->Schedule(time, impl);
248 }
249 
250 EventId
252 {
253 #ifdef ENABLE_DES_METRICS
254  DesMetrics::Get()->Trace(Now(), Time(0));
255 #endif
256  return GetImpl()->ScheduleNow(impl);
257 }
258 
259 EventId
261 {
262  return GetImpl()->ScheduleDestroy(impl);
263 }
264 
265 void
267 {
268  if (*PeekImpl() == nullptr)
269  {
270  return;
271  }
272  return GetImpl()->Remove(id);
273 }
274 
275 void
277 {
278  if (*PeekImpl() == nullptr)
279  {
280  return;
281  }
282  return GetImpl()->Cancel(id);
283 }
284 
285 bool
287 {
288  if (*PeekImpl() == nullptr)
289  {
290  return true;
291  }
292  return GetImpl()->IsExpired(id);
293 }
294 
295 Time
297 {
298  return Simulator::Now();
299 }
300 
301 Time
303 {
305  return GetImpl()->GetMaximumSimulationTime();
306 }
307 
308 uint32_t
310 {
311  return GetImpl()->GetContext();
312 }
313 
314 uint64_t
316 {
317  return GetImpl()->GetEventCount();
318 }
319 
320 uint32_t
322 {
324 
325  if (*PeekImpl() != nullptr)
326  {
327  return GetImpl()->GetSystemId();
328  }
329  else
330  {
331  return 0;
332  }
333 }
334 
335 void
337 {
338  NS_LOG_FUNCTION(impl);
339  if (*PeekImpl() != nullptr)
340  {
342  "It is not possible to set the implementation after calling any Simulator:: function. "
343  "Call Simulator::SetImplementation earlier or after Simulator::Destroy.");
344  }
345  *PeekImpl() = GetPointer(impl);
346  // Set the default scheduler
347  ObjectFactory factory;
348  StringValue s;
350  factory.SetTypeId(s.Get());
351  impl->SetScheduler(factory);
352  //
353  // Note: we call LogSetTimePrinter _after_ creating the implementation
354  // object because the act of creation can trigger calls to the logging
355  // framework which would call the TimePrinter function which would call
356  // Simulator::Now which would call Simulator::GetImpl, and, thus, get us
357  // in an infinite recursion until the stack explodes.
358  //
361 }
362 
365 {
367  return GetImpl();
368 }
369 
370 } // namespace ns3
NS_ASSERT() and NS_ASSERT_MSG() macro definitions.
void Trace(const Time &now, const Time &delay)
Trace an event to self at the time it is scheduled.
Definition: des-metrics.cc:101
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:107
An identifier for simulation events.
Definition: event-id.h:55
A simulation event.
Definition: event-impl.h:46
Hold a so-called 'global value'.
Definition: global-value.h:76
void GetValue(AttributeValue &value) const
Get the value.
Definition: global-value.cc:98
static TypeId GetTypeId()
Register this type.
Instantiate subclasses of ns3::Object.
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
static EventId DoScheduleDestroy(EventImpl *event)
Implementation of the various ScheduleDestroy methods.
Definition: simulator.cc:260
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static Ptr< SimulatorImpl > GetImplementation()
Get the SimulatorImpl singleton.
Definition: simulator.cc:364
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:276
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:140
static void ScheduleWithContext(uint32_t context, const Time &delay, FUNC f, Ts &&... args)
Schedule an event with the given context.
Definition: simulator.h:587
static bool IsFinished()
Check if the simulation should finish.
Definition: simulator.cc:169
static uint32_t GetSystemId()
Get the system id of this simulator.
Definition: simulator.cc:321
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
static void Run()
Run the simulation.
Definition: simulator.cc:176
static bool IsExpired(const EventId &id)
Check if an event has already run or been cancelled.
Definition: simulator.cc:286
static EventId ScheduleDestroy(FUNC f, Ts &&... args)
Schedule an event to run at the end of the simulation, when Simulator::Destroy() is called.
Definition: simulator.h:625
static void SetScheduler(ObjectFactory schedulerFactory)
Set the scheduler type with an ObjectFactory.
Definition: simulator.cc:162
static EventId DoScheduleNow(EventImpl *event)
Implementation of the various ScheduleNow methods.
Definition: simulator.cc:251
static uint64_t GetEventCount()
Get the number of events executed.
Definition: simulator.cc:315
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:606
static EventId DoSchedule(const Time &delay, EventImpl *event)
Implementation of the various Schedule methods.
Definition: simulator.cc:242
static Time GetMaximumSimulationTime()
Get the maximum representable simulation time.
Definition: simulator.cc:302
static void Remove(const EventId &id)
Remove an event from the event list.
Definition: simulator.cc:266
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:184
static void SetImplementation(Ptr< SimulatorImpl > impl)
Definition: simulator.cc:336
static uint32_t GetContext()
Get the current simulation context.
Definition: simulator.cc:309
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:208
The SimulatorImpl base class.
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...
virtual Time GetDelayLeft(const EventId &id) const =0
Get the remaining time until this event will execute.
virtual void SetScheduler(ObjectFactory schedulerFactory)=0
Set the Scheduler to be used to manage the event list.
virtual uint32_t GetSystemId() const =0
Get the system id of this simulator.
virtual void Run()=0
Run the simulation.
virtual EventId Schedule(const Time &delay, EventImpl *event)=0
Schedule a future event execution (in the same context).
virtual bool IsExpired(const EventId &id) const =0
Check if an event has already run or been cancelled.
virtual void Remove(const EventId &id)=0
Remove an event from the event list.
virtual Time GetMaximumSimulationTime() const =0
Get the maximum representable simulation time.
virtual void ScheduleWithContext(uint32_t context, const Time &delay, EventImpl *event)=0
Schedule a future event execution (in a different context).
virtual EventId ScheduleNow(EventImpl *event)=0
Schedule an event to run at the current virtual time.
virtual Time Now() const =0
Return the current simulation virtual time.
virtual bool IsFinished() const =0
Check if the simulation should finish.
virtual uint64_t GetEventCount() const =0
Get the number of events executed.
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...
virtual uint32_t GetContext() const =0
Get the current simulation context.
virtual void Stop()=0
Tell the Simulator the calling event should be the last one executed.
static DesMetrics * Get()
Get a pointer to the singleton instance.
Definition: singleton.h:100
Hold variables of type string.
Definition: string.h:56
std::string Get() const
Definition: string.cc:31
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
static void ClearMarkedTimes()
Remove all MarkedTimes.
Definition: time.cc:296
AttributeValue implementation for TypeId.
Definition: type-id.h:600
ns3::DesMetrics declaration.
ns3::EventImpl declarations.
ns3::GlobalValue declaration.
Ptr< const AttributeChecker > MakeStringChecker()
Definition: string.cc:30
Ptr< const AttributeChecker > MakeTypeIdChecker()
Definition: type-id.cc:1254
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
void DefaultNodePrinter(std::ostream &os)
Default node id printer implementation.
Definition: node-printer.cc:39
static GlobalValue g_schedTypeImpl
The specific event scheduler implementation to use.
Definition: simulator.cc:77
static GlobalValue g_simTypeImpl
The specific simulator implementation to use.
Definition: simulator.cc:64
static SimulatorImpl * GetImpl()
Get the SimulatorImpl singleton.
Definition: simulator.cc:102
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:296
static SimulatorImpl ** PeekImpl()
Get the static SimulatorImpl instance.
Definition: simulator.cc:89
Debug message logging.
ns3::MapScheduler declaration.
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:848
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void LogSetTimePrinter(TimePrinter printer)
Set the TimePrinter function to be used to prepend log messages with the simulation time.
Definition: log.cc:512
U * GetPointer(const Ptr< U > &p)
Definition: ptr.h:495
void DefaultTimePrinter(std::ostream &os)
Default Time printer.
Definition: time-printer.cc:40
void LogSetNodePrinter(NodePrinter printer)
Set the LogNodePrinter function to be used to prepend log messages with the node id.
Definition: log.cc:529
ns3::ObjectFactory class declaration.
ns3::Ptr smart pointer declaration and implementation.
ns3::Scheduler abstract base class, ns3::Scheduler::Event and ns3::Scheduler::EventKey declarations.
ns3::SimulatorImpl declaration.
ns3::Simulator declaration.
ns3::StringValue attribute value declarations.