A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
simulator.cc
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 
27 #include "ptr.h"
28 #include "string.h"
29 #include "object-factory.h"
30 #include "global-value.h"
31 #include "assert.h"
32 #include "log.h"
33 
34 #include <cmath>
35 #include <fstream>
36 #include <list>
37 #include <vector>
38 #include <iostream>
39 
40 // Note: Logging in this file is largely avoided due to the
41 // number of calls that are made to these functions and the possibility
42 // of causing recursions leading to stack overflow
43 
44 NS_LOG_COMPONENT_DEFINE ("Simulator");
45 
46 namespace ns3 {
47 
48 GlobalValue g_simTypeImpl = GlobalValue ("SimulatorImplementationType",
49  "The object class to use as the simulator implementation",
50  StringValue ("ns3::DefaultSimulatorImpl"),
51  MakeStringChecker ());
52 
53 GlobalValue g_schedTypeImpl = GlobalValue ("SchedulerType",
54  "The object class to use as the scheduler implementation",
55  TypeIdValue (MapScheduler::GetTypeId ()),
56  MakeTypeIdChecker ());
57 
58 static void
59 TimePrinter (std::ostream &os)
60 {
61  os << Simulator::Now ().GetSeconds () << "s";
62 }
63 
64 static void
65 NodePrinter (std::ostream &os)
66 {
67  if (Simulator::GetContext () == 0xffffffff)
68  {
69  os << "-1";
70  }
71  else
72  {
73  os << Simulator::GetContext ();
74  }
75 }
76 
77 static SimulatorImpl **PeekImpl (void)
78 {
79  static SimulatorImpl *impl = 0;
80  return &impl;
81 }
82 
83 static SimulatorImpl * GetImpl (void)
84 {
85  SimulatorImpl **pimpl = PeekImpl ();
86  /* Please, don't include any calls to logging macros in this function
87  * or pay the price, that is, stack explosions.
88  */
89  if (*pimpl == 0)
90  {
91  {
92  ObjectFactory factory;
93  StringValue s;
94 
95  g_simTypeImpl.GetValue (s);
96  factory.SetTypeId (s.Get ());
97  *pimpl = GetPointer (factory.Create<SimulatorImpl> ());
98  }
99  {
100  ObjectFactory factory;
101  StringValue s;
102  g_schedTypeImpl.GetValue (s);
103  factory.SetTypeId (s.Get ());
104  (*pimpl)->SetScheduler (factory);
105  }
106 
107 //
108 // Note: we call LogSetTimePrinter _after_ creating the implementation
109 // object because the act of creation can trigger calls to the logging
110 // framework which would call the TimePrinter function which would call
111 // Simulator::Now which would call Simulator::GetImpl, and, thus, get us
112 // in an infinite recursion until the stack explodes.
113 //
114  LogSetTimePrinter (&TimePrinter);
115  LogSetNodePrinter (&NodePrinter);
116  }
117  return *pimpl;
118 }
119 
120 void
122 {
124 
125  SimulatorImpl **pimpl = PeekImpl ();
126  if (*pimpl == 0)
127  {
128  return;
129  }
130  /* Note: we have to call LogSetTimePrinter (0) below because if we do not do
131  * this, and restart a simulation after this call to Destroy, (which is
132  * legal), Simulator::GetImpl will trigger again an infinite recursion until
133  * the stack explodes.
134  */
135  LogSetTimePrinter (0);
136  LogSetNodePrinter (0);
137  (*pimpl)->Destroy ();
138  (*pimpl)->Unref ();
139  *pimpl = 0;
140 }
141 
142 void
144 {
145  NS_LOG_FUNCTION (schedulerFactory);
146  GetImpl ()->SetScheduler (schedulerFactory);
147 }
148 
149 bool
151 {
153  return GetImpl ()->IsFinished ();
154 }
155 
156 void
158 {
160  GetImpl ()->Run ();
161 }
162 
163 void
165 {
167  NS_LOG_LOGIC ("stop");
168  GetImpl ()->Stop ();
169 }
170 
171 void
172 Simulator::Stop (Time const &time)
173 {
174  NS_LOG_FUNCTION (time);
175  GetImpl ()->Stop (time);
176 }
177 
178 Time
180 {
181  /* Please, don't include any calls to logging macros in this function
182  * or pay the price, that is, stack explosions.
183  */
184  return GetImpl ()->Now ();
185 }
186 
187 Time
189 {
190  NS_LOG_FUNCTION (&id);
191  return GetImpl ()->GetDelayLeft (id);
192 }
193 
194 EventId
195 Simulator::Schedule (Time const &time, const Ptr<EventImpl> &ev)
196 {
197  return DoSchedule (time, GetPointer (ev));
198 }
199 
200 EventId
202 {
203  return DoScheduleNow (GetPointer (ev));
204 }
205 void
206 Simulator::ScheduleWithContext (uint32_t context, const Time &time, EventImpl *impl)
207 {
208  return GetImpl ()->ScheduleWithContext (context, time, impl);
209 }
210 EventId
212 {
213  return DoScheduleDestroy (GetPointer (ev));
214 }
215 EventId
216 Simulator::DoSchedule (Time const &time, EventImpl *impl)
217 {
218  return GetImpl ()->Schedule (time, impl);
219 }
220 EventId
221 Simulator::DoScheduleNow (EventImpl *impl)
222 {
223  return GetImpl ()->ScheduleNow (impl);
224 }
225 EventId
226 Simulator::DoScheduleDestroy (EventImpl *impl)
227 {
228  return GetImpl ()->ScheduleDestroy (impl);
229 }
230 
231 
232 EventId
233 Simulator::Schedule (Time const &time, void (*f)(void))
234 {
235  return DoSchedule (time, MakeEvent (f));
236 }
237 
238 void
239 Simulator::ScheduleWithContext (uint32_t context, Time const &time, void (*f)(void))
240 {
241  return ScheduleWithContext (context, time, MakeEvent (f));
242 }
243 
244 EventId
245 Simulator::ScheduleNow (void (*f)(void))
246 {
247  return DoScheduleNow (MakeEvent (f));
248 }
249 
250 EventId
251 Simulator::ScheduleDestroy (void (*f)(void))
252 {
253  return DoScheduleDestroy (MakeEvent (f));
254 }
255 
256 void
258 {
259  if (*PeekImpl () == 0)
260  {
261  return;
262  }
263  return GetImpl ()->Remove (ev);
264 }
265 
266 void
268 {
269  if (*PeekImpl () == 0)
270  {
271  return;
272  }
273  return GetImpl ()->Cancel (ev);
274 }
275 
276 bool
278 {
279  if (*PeekImpl () == 0)
280  {
281  return true;
282  }
283  return GetImpl ()->IsExpired (id);
284 }
285 
286 Time Now (void)
287 {
288  return Time (Simulator::Now ());
289 }
290 
291 Time
293 {
295  return GetImpl ()->GetMaximumSimulationTime ();
296 }
297 
298 uint32_t
300 {
301  return GetImpl ()->GetContext ();
302 }
303 
304 uint32_t
306 {
308 
309  if (*PeekImpl () != 0)
310  {
311  return GetImpl ()->GetSystemId ();
312  }
313  else
314  {
315  return 0;
316  }
317 }
318 
319 void
321 {
322  NS_LOG_FUNCTION (impl);
323  if (*PeekImpl () != 0)
324  {
325  NS_FATAL_ERROR ("It is not possible to set the implementation after calling any Simulator:: function. Call Simulator::SetImplementation earlier or after Simulator::Destroy.");
326  }
327  *PeekImpl () = GetPointer (impl);
328  // Set the default scheduler
329  ObjectFactory factory;
330  StringValue s;
331  g_schedTypeImpl.GetValue (s);
332  factory.SetTypeId (s.Get ());
333  impl->SetScheduler (factory);
334 //
335 // Note: we call LogSetTimePrinter _after_ creating the implementation
336 // object because the act of creation can trigger calls to the logging
337 // framework which would call the TimePrinter function which would call
338 // Simulator::Now which would call Simulator::GetImpl, and, thus, get us
339 // in an infinite recursion until the stack explodes.
340 //
341  LogSetTimePrinter (&TimePrinter);
342  LogSetNodePrinter (&NodePrinter);
343 }
345 Simulator::GetImplementation (void)
346 {
348  return GetImpl ();
349 }
350 
351 
352 
353 } // namespace ns3
354 
static Time GetDelayLeft(const EventId &id)
Definition: simulator.cc:188
keep track of time unit.
Definition: nstime.h:149
virtual void ScheduleWithContext(uint32_t context, Time const &time, EventImpl *event)=0
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
static void SetImplementation(Ptr< SimulatorImpl > impl)
Definition: simulator.cc:320
virtual bool IsExpired(const EventId &ev) const =0
hold variables of type string
Definition: string.h:19
static uint32_t GetSystemId(void)
Definition: simulator.cc:305
virtual Time Now(void) const =0
static uint32_t GetContext(void)
Definition: simulator.cc:299
static void Run(void)
Definition: simulator.cc:157
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
virtual EventId ScheduleNow(EventImpl *event)=0
void SetTypeId(TypeId tid)
static void Cancel(const EventId &id)
Definition: simulator.cc:267
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
virtual void SetScheduler(ObjectFactory schedulerFactory)=0
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
virtual void Run(void)=0
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
virtual Time GetMaximumSimulationTime(void) const =0
virtual bool IsFinished(void) const =0
double GetSeconds(void) const
Definition: nstime.h:262
virtual Time GetDelayLeft(const EventId &id) const =0
static void ScheduleWithContext(uint32_t context, Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:900
virtual EventId ScheduleDestroy(EventImpl *event)=0
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
static void Destroy(void)
Definition: simulator.cc:121
static void Remove(const EventId &id)
Definition: simulator.cc:257
virtual void Cancel(const EventId &ev)=0
static bool IsExpired(const EventId &id)
Definition: simulator.cc:277
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Definition: simulator.h:981
static void SetScheduler(ObjectFactory schedulerFactory)
Definition: simulator.cc:143
static Time Now(void)
Definition: simulator.cc:179
virtual EventId Schedule(Time const &time, EventImpl *event)=0
instantiate subclasses of ns3::Object.
a simulation event
Definition: event-impl.h:39
virtual void Remove(const EventId &ev)=0
an identifier for simulation events.
Definition: event-id.h:46
static void Stop(void)
Definition: simulator.cc:164
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:286
virtual void Stop(void)=0
static bool IsFinished(void)
Definition: simulator.cc:150
static EventId ScheduleDestroy(MEM mem_ptr, OBJ obj)
Definition: simulator.h:1072
virtual uint32_t GetSystemId() const =0
virtual uint32_t GetContext(void) const =0
static Time GetMaximumSimulationTime(void)
Definition: simulator.cc:292
void GetValue(AttributeValue &value) const