A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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
42/**
43 * \file
44 * \ingroup simulator
45 * ns3::Simulator implementation, as well as implementation pointer,
46 * global scheduler implementation.
47 */
48
49namespace 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
55NS_LOG_COMPONENT_DEFINE("Simulator");
56
58
59/**
60 * \ingroup simulator
61 * \anchor GlobalValueSimulatorImplementationType
62 * The specific simulator implementation to use.
63 *
64 * Must be derived from SimulatorImpl.
65 */
67 GlobalValue("SimulatorImplementationType",
68 "The object class to use as the simulator implementation",
69 StringValue("ns3::DefaultSimulatorImpl"),
71
72/**
73 * \ingroup scheduler
74 * \anchor GlobalValueSchedulerType
75 * The specific event scheduler implementation to use.
76 *
77 * Must be derived from Scheduler.
78 */
80 GlobalValue("SchedulerType",
81 "The object class to use as the scheduler implementation",
84
85/**
86 * \ingroup simulator
87 * \brief Get the static SimulatorImpl instance.
88 * \return The SimulatorImpl instance pointer.
89 */
90static SimulatorImpl**
92{
93 static SimulatorImpl* impl = nullptr;
94 return &impl;
95}
96
97/**
98 * \ingroup simulator
99 * \brief Get the SimulatorImpl singleton.
100 * \return The singleton pointer.
101 * \see Simulator::GetImplementation()
102 */
103static SimulatorImpl*
105{
106 SimulatorImpl** pimpl = PeekImpl();
107 /* Please, don't include any calls to logging macros in this function
108 * or pay the price, that is, stack explosions.
109 */
110 if (*pimpl == nullptr)
111 {
112 {
113 ObjectFactory factory;
114 StringValue s;
115
117 factory.SetTypeId(s.Get());
118 *pimpl = GetPointer(factory.Create<SimulatorImpl>());
119 }
120 {
121 ObjectFactory factory;
122 StringValue s;
124 factory.SetTypeId(s.Get());
125 (*pimpl)->SetScheduler(factory);
126 }
127
128 //
129 // Note: we call LogSetTimePrinter _after_ creating the implementation
130 // object because the act of creation can trigger calls to the logging
131 // framework which would call the TimePrinter function which would call
132 // Simulator::Now which would call Simulator::GetImpl, and, thus, get us
133 // in an infinite recursion until the stack explodes.
134 //
137 }
138 return *pimpl;
139}
140
141void
143{
145
146 SimulatorImpl** pimpl = PeekImpl();
147 if (*pimpl == nullptr)
148 {
149 return;
150 }
151 /* Note: we have to call LogSetTimePrinter (0) below because if we do not do
152 * this, and restart a simulation after this call to Destroy, (which is
153 * legal), Simulator::GetImpl will trigger again an infinite recursion until
154 * the stack explodes.
155 */
156 LogSetTimePrinter(nullptr);
157 LogSetNodePrinter(nullptr);
158 (*pimpl)->Destroy();
159 (*pimpl)->Unref();
160 *pimpl = nullptr;
161}
162
163void
165{
166 NS_LOG_FUNCTION(schedulerFactory);
167 GetImpl()->SetScheduler(schedulerFactory);
168}
169
170bool
172{
174 return GetImpl()->IsFinished();
175}
176
177void
179{
182 GetImpl()->Run();
183}
184
185void
187{
189 NS_LOG_LOGIC("stop");
190 GetImpl()->Stop();
191}
192
195{
196 NS_LOG_FUNCTION(delay);
197 m_stopEvent = GetImpl()->Stop(delay);
198 return m_stopEvent;
199}
200
203{
204 return m_stopEvent;
205}
206
207Time
209{
210 /* Please, don't include any calls to logging macros in this function
211 * or pay the price, that is, stack explosions.
212 */
213 return GetImpl()->Now();
214}
215
216Time
218{
219 NS_LOG_FUNCTION(&id);
220 return GetImpl()->GetDelayLeft(id);
221}
222
224Simulator::Schedule(const Time& delay, const Ptr<EventImpl>& event)
225{
226 return DoSchedule(delay, GetPointer(event));
227}
228
231{
232 return DoScheduleNow(GetPointer(ev));
233}
234
235void
237{
238#ifdef ENABLE_DES_METRICS
239 DesMetrics::Get()->TraceWithContext(context, Now(), delay);
240#endif
241 return GetImpl()->ScheduleWithContext(context, delay, impl);
242}
243
246{
247 return DoScheduleDestroy(GetPointer(ev));
248}
249
252{
253#ifdef ENABLE_DES_METRICS
254 DesMetrics::Get()->Trace(Now(), time);
255#endif
256 return GetImpl()->Schedule(time, impl);
257}
258
261{
262#ifdef ENABLE_DES_METRICS
263 DesMetrics::Get()->Trace(Now(), Time(0));
264#endif
265 return GetImpl()->ScheduleNow(impl);
266}
267
270{
271 return GetImpl()->ScheduleDestroy(impl);
272}
273
274void
276{
277 if (*PeekImpl() == nullptr)
278 {
279 return;
280 }
281 return GetImpl()->Remove(id);
282}
283
284void
286{
287 if (*PeekImpl() == nullptr)
288 {
289 return;
290 }
291 return GetImpl()->Cancel(id);
292}
293
294bool
296{
297 if (*PeekImpl() == nullptr)
298 {
299 return true;
300 }
301 return GetImpl()->IsExpired(id);
302}
303
304Time
306{
307 return Simulator::Now();
308}
309
310Time
312{
315}
316
319{
320 return GetImpl()->GetContext();
321}
322
323uint64_t
325{
326 return GetImpl()->GetEventCount();
327}
328
331{
333
334 if (*PeekImpl() != nullptr)
335 {
336 return GetImpl()->GetSystemId();
337 }
338 else
339 {
340 return 0;
341 }
342}
343
344void
346{
347 NS_LOG_FUNCTION(impl);
348 if (*PeekImpl() != nullptr)
349 {
351 "It is not possible to set the implementation after calling any Simulator:: function. "
352 "Call Simulator::SetImplementation earlier or after Simulator::Destroy.");
353 }
354 *PeekImpl() = GetPointer(impl);
355 // Set the default scheduler
356 ObjectFactory factory;
357 StringValue s;
359 factory.SetTypeId(s.Get());
360 impl->SetScheduler(factory);
361 //
362 // Note: we call LogSetTimePrinter _after_ creating the implementation
363 // object because the act of creation can trigger calls to the logging
364 // framework which would call the TimePrinter function which would call
365 // Simulator::Now which would call Simulator::GetImpl, and, thus, get us
366 // in an infinite recursion until the stack explodes.
367 //
370}
371
374{
376 return GetImpl();
377}
378
379} // 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:77
static EventId DoScheduleDestroy(EventImpl *event)
Implementation of the various ScheduleDestroy methods.
Definition: simulator.cc:269
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static Ptr< SimulatorImpl > GetImplementation()
Get the SimulatorImpl singleton.
Definition: simulator.cc:373
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:285
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void ScheduleWithContext(uint32_t context, const Time &delay, FUNC f, Ts &&... args)
Schedule an event with the given context.
Definition: simulator.h:588
static EventId m_stopEvent
Stop event (if present)
Definition: simulator.h:534
static bool IsFinished()
Check if the simulation should finish.
Definition: simulator.cc:171
static uint32_t GetSystemId()
Get the system id of this simulator.
Definition: simulator.cc:330
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static void Run()
Run the simulation.
Definition: simulator.cc:178
static bool IsExpired(const EventId &id)
Check if an event has already run or been cancelled.
Definition: simulator.cc:295
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:622
static void SetScheduler(ObjectFactory schedulerFactory)
Set the scheduler type with an ObjectFactory.
Definition: simulator.cc:164
static EventId DoScheduleNow(EventImpl *event)
Implementation of the various ScheduleNow methods.
Definition: simulator.cc:260
static uint64_t GetEventCount()
Get the number of events executed.
Definition: simulator.cc:324
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:605
static EventId DoSchedule(const Time &delay, EventImpl *event)
Implementation of the various Schedule methods.
Definition: simulator.cc:251
static Time GetMaximumSimulationTime()
Get the maximum representable simulation time.
Definition: simulator.cc:311
static void Remove(const EventId &id)
Remove an event from the event list.
Definition: simulator.cc:275
static EventId GetStopEvent()
Returns the Stop Event, or an invalid event if the simulation does not have a scheduled stop time.
Definition: simulator.cc:202
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
static void SetImplementation(Ptr< SimulatorImpl > impl)
Definition: simulator.cc:345
static uint32_t GetContext()
Get the current simulation context.
Definition: simulator.cc:318
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:217
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:107
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:598
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:1251
#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:79
static SimulatorImpl ** PeekImpl()
Get the static SimulatorImpl instance.
Definition: simulator.cc:91
static GlobalValue g_simTypeImpl
The specific simulator implementation to use.
Definition: simulator.cc:66
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:305
static SimulatorImpl * GetImpl()
Get the SimulatorImpl singleton.
Definition: simulator.cc:104
Debug message logging.
ns3::MapScheduler declaration.
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:492
U * GetPointer(const Ptr< U > &p)
Definition: ptr.h:461
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:509
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.