A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 
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 <math.h>
35 #include <fstream>
36 #include <list>
37 #include <vector>
38 #include <iostream>
39 
40 NS_LOG_COMPONENT_DEFINE ("Simulator");
41 
42 namespace ns3 {
43 
44 GlobalValue g_simTypeImpl = GlobalValue ("SimulatorImplementationType",
45  "The object class to use as the simulator implementation",
46  StringValue ("ns3::DefaultSimulatorImpl"),
47  MakeStringChecker ());
48 
50  "The object class to use as the scheduler implementation",
52  MakeTypeIdChecker ());
53 
54 static void
55 TimePrinter (std::ostream &os)
56 {
57  os << Simulator::Now ().GetSeconds () << "s";
58 }
59 
60 static void
61 NodePrinter (std::ostream &os)
62 {
63  if (Simulator::GetContext () == 0xffffffff)
64  {
65  os << "-1";
66  }
67  else
68  {
69  os << Simulator::GetContext ();
70  }
71 }
72 
73 static SimulatorImpl **PeekImpl (void)
74 {
75  static SimulatorImpl *impl = 0;
76  return &impl;
77 }
78 
79 static SimulatorImpl * GetImpl (void)
80 {
81  SimulatorImpl **pimpl = PeekImpl ();
82  /* Please, don't include any calls to logging macros in this function
83  * or pay the price, that is, stack explosions.
84  */
85  if (*pimpl == 0)
86  {
87  {
88  ObjectFactory factory;
89  StringValue s;
90 
92  factory.SetTypeId (s.Get ());
93  *pimpl = GetPointer (factory.Create<SimulatorImpl> ());
94  }
95  {
96  ObjectFactory factory;
97  StringValue s;
99  factory.SetTypeId (s.Get ());
100  (*pimpl)->SetScheduler (factory);
101  }
102 
103 //
104 // Note: we call LogSetTimePrinter _after_ creating the implementation
105 // object because the act of creation can trigger calls to the logging
106 // framework which would call the TimePrinter function which would call
107 // Simulator::Now which would call Simulator::GetImpl, and, thus, get us
108 // in an infinite recursion until the stack explodes.
109 //
112  }
113  return *pimpl;
114 }
115 
116 void
118 {
120 
121  SimulatorImpl **pimpl = PeekImpl ();
122  if (*pimpl == 0)
123  {
124  return;
125  }
126  /* Note: we have to call LogSetTimePrinter (0) below because if we do not do
127  * this, and restart a simulation after this call to Destroy, (which is
128  * legal), Simulator::GetImpl will trigger again an infinite recursion until
129  * the stack explodes.
130  */
131  LogSetTimePrinter (0);
132  LogSetNodePrinter (0);
133  (*pimpl)->Destroy ();
134  (*pimpl)->Unref ();
135  *pimpl = 0;
136 }
137 
138 void
140 {
141  NS_LOG_FUNCTION (schedulerFactory);
142  GetImpl ()->SetScheduler (schedulerFactory);
143 }
144 
145 bool
147 {
149  return GetImpl ()->IsFinished ();
150 }
151 
152 void
154 {
156  GetImpl ()->Run ();
157 }
158 
159 void
161 {
162  NS_LOG_LOGIC ("stop");
163  GetImpl ()->Stop ();
164 }
165 
166 void
167 Simulator::Stop (Time const &time)
168 {
169  NS_LOG_FUNCTION (time);
170  GetImpl ()->Stop (time);
171 }
172 
173 Time
175 {
176  /* Please, don't include any calls to logging macros in this function
177  * or pay the price, that is, stack explosions.
178  */
179  return GetImpl ()->Now ();
180 }
181 
182 Time
184 {
185  NS_LOG_FUNCTION (&id);
186  return GetImpl ()->GetDelayLeft (id);
187 }
188 
189 EventId
190 Simulator::Schedule (Time const &time, const Ptr<EventImpl> &ev)
191 {
192  NS_LOG_FUNCTION (time << ev);
193  return DoSchedule (time, GetPointer (ev));
194 }
195 
196 EventId
198 {
199  NS_LOG_FUNCTION (ev);
200  return DoScheduleNow (GetPointer (ev));
201 }
202 void
203 Simulator::ScheduleWithContext (uint32_t context, const Time &time, EventImpl *impl)
204 {
205  return GetImpl ()->ScheduleWithContext (context, time, impl);
206 }
207 EventId
209 {
210  NS_LOG_FUNCTION (ev);
211  return DoScheduleDestroy (GetPointer (ev));
212 }
213 EventId
215 {
216  return GetImpl ()->Schedule (time, impl);
217 }
218 EventId
220 {
221  return GetImpl ()->ScheduleNow (impl);
222 }
223 EventId
225 {
226  return GetImpl ()->ScheduleDestroy (impl);
227 }
228 
229 
230 EventId
231 Simulator::Schedule (Time const &time, void (*f)(void))
232 {
233  NS_LOG_FUNCTION (time << f);
234  return DoSchedule (time, MakeEvent (f));
235 }
236 
237 void
238 Simulator::ScheduleWithContext (uint32_t context, Time const &time, void (*f)(void))
239 {
240  NS_LOG_FUNCTION (time << context << f);
241  return ScheduleWithContext (context, time, MakeEvent (f));
242 }
243 
244 EventId
245 Simulator::ScheduleNow (void (*f)(void))
246 {
247  NS_LOG_FUNCTION (f);
248  return DoScheduleNow (MakeEvent (f));
249 }
250 
251 EventId
252 Simulator::ScheduleDestroy (void (*f)(void))
253 {
254  NS_LOG_FUNCTION (f);
255  return DoScheduleDestroy (MakeEvent (f));
256 }
257 
258 void
260 {
261  NS_LOG_FUNCTION (&ev);
262  if (*PeekImpl () == 0)
263  {
264  return;
265  }
266  return GetImpl ()->Remove (ev);
267 }
268 
269 void
271 {
272  NS_LOG_FUNCTION (&ev);
273  if (*PeekImpl () == 0)
274  {
275  return;
276  }
277  return GetImpl ()->Cancel (ev);
278 }
279 
280 bool
282 {
283  NS_LOG_FUNCTION (&id);
284  if (*PeekImpl () == 0)
285  {
286  return true;
287  }
288  return GetImpl ()->IsExpired (id);
289 }
290 
291 Time Now (void)
292 {
294  return Time (Simulator::Now ());
295 }
296 
297 Time
299 {
301  return GetImpl ()->GetMaximumSimulationTime ();
302 }
303 
304 uint32_t
306 {
307  return GetImpl ()->GetContext ();
308 }
309 
310 uint32_t
312 {
314 
315  if (*PeekImpl () != 0)
316  {
317  return GetImpl ()->GetSystemId ();
318  }
319  else
320  {
321  return 0;
322  }
323 }
324 
325 void
327 {
328  if (*PeekImpl () != 0)
329  {
330  NS_FATAL_ERROR ("It is not possible to set the implementation after calling any Simulator:: function. Call Simulator::SetImplementation earlier or after Simulator::Destroy.");
331  }
332  *PeekImpl () = GetPointer (impl);
333  // Set the default scheduler
334  ObjectFactory factory;
335  StringValue s;
337  factory.SetTypeId (s.Get ());
338  impl->SetScheduler (factory);
339 //
340 // Note: we call LogSetTimePrinter _after_ creating the implementation
341 // object because the act of creation can trigger calls to the logging
342 // framework which would call the TimePrinter function which would call
343 // Simulator::Now which would call Simulator::GetImpl, and, thus, get us
344 // in an infinite recursion until the stack explodes.
345 //
348 }
351 {
352  return GetImpl ();
353 }
354 
355 
356 
357 } // namespace ns3
358