File: | /tmp/asd-nat/home/nat/Work/ns-3-dev-git/build/../src/core/model/simulator.cc |
Location: | line 173, column 9 |
Description: | Called C++ object pointer is null |
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 | ||||
42 | /** | |||
43 | * \file | |||
44 | * \ingroup simulator | |||
45 | * ns3::Simulator implementation, as well as implementation pointer, | |||
46 | * global scheduler implementation, and default ns3::NodePrinter | |||
47 | * and ns3::TimePrinter. | |||
48 | */ | |||
49 | ||||
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")static ns3::LogComponent g_log = ns3::LogComponent ("Simulator" , "../src/core/model/simulator.cc"); | |||
56 | ||||
57 | /** | |||
58 | * \ingroup simulator | |||
59 | * The specific simulator implementation to use. | |||
60 | * | |||
61 | * Must be derived from SimulatorImpl. | |||
62 | */ | |||
63 | static GlobalValue g_simTypeImpl = GlobalValue | |||
64 | ("SimulatorImplementationType", | |||
65 | "The object class to use as the simulator implementation", | |||
66 | StringValue ("ns3::DefaultSimulatorImpl"), | |||
67 | MakeStringChecker ()); | |||
68 | ||||
69 | /** | |||
70 | * \ingroup scheduler | |||
71 | * The specific event scheduler implementation to use. | |||
72 | * | |||
73 | * Must be derived from Scheduler. | |||
74 | */ | |||
75 | static GlobalValue g_schedTypeImpl = GlobalValue ("SchedulerType", | |||
76 | "The object class to use as the scheduler implementation", | |||
77 | TypeIdValue (MapScheduler::GetTypeId ()), | |||
78 | MakeTypeIdChecker ()); | |||
79 | ||||
80 | /** | |||
81 | * \ingroup logging | |||
82 | * Default TimePrinter implementation. | |||
83 | * | |||
84 | * \param [in,out] os The output stream to print the time on. | |||
85 | */ | |||
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 | ||||
116 | /** | |||
117 | * \ingroup logging | |||
118 | * Default node id printer implementation. | |||
119 | * | |||
120 | * \param [in,out] os The output stream to print the node id on. | |||
121 | */ | |||
122 | static void | |||
123 | NodePrinter (std::ostream &os) | |||
124 | { | |||
125 | if (Simulator::GetContext () == Simulator::NO_CONTEXT) | |||
| ||||
126 | { | |||
127 | os << "-1"; | |||
128 | } | |||
129 | else | |||
130 | { | |||
131 | os << Simulator::GetContext (); | |||
132 | } | |||
133 | } | |||
134 | ||||
135 | /** | |||
136 | * \ingroup simulator | |||
137 | * \brief Get the static SimulatorImpl instance. | |||
138 | * \return The SimulatorImpl instance pointer. | |||
139 | */ | |||
140 | static SimulatorImpl **PeekImpl (void) | |||
141 | { | |||
142 | static SimulatorImpl *impl = 0; | |||
143 | return &impl; | |||
144 | } | |||
145 | ||||
146 | /** | |||
147 | * \ingroup simulator | |||
148 | * \brief Get the SimulatorImpl singleton. | |||
149 | * \return The singleton pointer. | |||
150 | * \see Simulator::GetImplementation() | |||
151 | */ | |||
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 | // | |||
183 | LogSetTimePrinter (&TimePrinter); | |||
184 | LogSetNodePrinter (&NodePrinter); | |||
185 | } | |||
186 | return *pimpl; | |||
187 | } | |||
188 | ||||
189 | void | |||
190 | Simulator::Destroy (void) | |||
191 | { | |||
192 | NS_LOG_FUNCTION_NOARGS ()do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "()" << std::endl; } } while (false ); | |||
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 | |||
212 | Simulator::SetScheduler (ObjectFactory schedulerFactory) | |||
213 | { | |||
214 | NS_LOG_FUNCTION (schedulerFactory)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << schedulerFactory; std::clog << ")" << std::endl; } } while (false); | |||
215 | GetImpl ()->SetScheduler (schedulerFactory); | |||
216 | } | |||
217 | ||||
218 | bool | |||
219 | Simulator::IsFinished (void) | |||
220 | { | |||
221 | NS_LOG_FUNCTION_NOARGS ()do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "()" << std::endl; } } while (false ); | |||
222 | return GetImpl ()->IsFinished (); | |||
223 | } | |||
224 | ||||
225 | void | |||
226 | Simulator::Run (void) | |||
227 | { | |||
228 | NS_LOG_FUNCTION_NOARGS ()do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "()" << std::endl; } } while (false ); | |||
229 | Time::ClearMarkedTimes (); | |||
230 | GetImpl ()->Run (); | |||
231 | } | |||
232 | ||||
233 | void | |||
234 | Simulator::Stop (void) | |||
235 | { | |||
236 | NS_LOG_FUNCTION_NOARGS ()do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "()" << std::endl; } } while (false ); | |||
237 | NS_LOG_LOGIC ("stop")do { if (g_log.IsEnabled (ns3::LOG_LOGIC)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_LOGIC) << "] "; }; std::clog << "stop" << std::endl; } } while (false); | |||
238 | GetImpl ()->Stop (); | |||
239 | } | |||
240 | ||||
241 | void | |||
242 | Simulator::Stop (Time const &delay) | |||
243 | { | |||
244 | NS_LOG_FUNCTION (delay)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << delay; std::clog << ")" << std::endl; } } while ( false); | |||
245 | GetImpl ()->Stop (delay); | |||
246 | } | |||
247 | ||||
248 | Time | |||
249 | Simulator::Now (void) | |||
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 | |||
258 | Simulator::GetDelayLeft (const EventId &id) | |||
259 | { | |||
260 | NS_LOG_FUNCTION (&id)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << &id; std::clog << ")" << std::endl; } } while (false); | |||
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 | |||
271 | Simulator::ScheduleNow (const Ptr<EventImpl> &ev) | |||
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 | |||
284 | Simulator::ScheduleDestroy (const Ptr<EventImpl> &ev) | |||
285 | { | |||
286 | return DoScheduleDestroy (GetPointer (ev)); | |||
287 | } | |||
288 | EventId | |||
289 | Simulator::DoSchedule (Time const &time, EventImpl *impl) | |||
290 | { | |||
291 | #ifdef ENABLE_DES_METRICS | |||
292 | DesMetrics::Get ()->Trace (Now (), time); | |||
293 | #endif | |||
294 | return GetImpl ()->Schedule (time, impl); | |||
295 | } | |||
296 | EventId | |||
297 | Simulator::DoScheduleNow (EventImpl *impl) | |||
298 | { | |||
299 | #ifdef ENABLE_DES_METRICS | |||
300 | DesMetrics::Get ()->Trace (Now (), Time (0)); | |||
301 | #endif | |||
302 | return GetImpl ()->ScheduleNow (impl); | |||
303 | } | |||
304 | EventId | |||
305 | Simulator::DoScheduleDestroy (EventImpl *impl) | |||
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 | |||
330 | Simulator::ScheduleDestroy (void (*f)(void)) | |||
331 | { | |||
332 | return DoScheduleDestroy (MakeEvent (f)); | |||
333 | } | |||
334 | ||||
335 | void | |||
336 | Simulator::Remove (const EventId &id) | |||
337 | { | |||
338 | if (*PeekImpl () == 0) | |||
339 | { | |||
340 | return; | |||
341 | } | |||
342 | return GetImpl ()->Remove (id); | |||
343 | } | |||
344 | ||||
345 | void | |||
346 | Simulator::Cancel (const EventId &id) | |||
347 | { | |||
348 | if (*PeekImpl () == 0) | |||
349 | { | |||
350 | return; | |||
351 | } | |||
352 | return GetImpl ()->Cancel (id); | |||
353 | } | |||
354 | ||||
355 | bool | |||
356 | Simulator::IsExpired (const EventId &id) | |||
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 | |||
371 | Simulator::GetMaximumSimulationTime (void) | |||
372 | { | |||
373 | NS_LOG_FUNCTION_NOARGS ()do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "()" << std::endl; } } while (false ); | |||
374 | return GetImpl ()->GetMaximumSimulationTime (); | |||
375 | } | |||
376 | ||||
377 | uint32_t | |||
378 | Simulator::GetContext (void) | |||
379 | { | |||
380 | return GetImpl ()->GetContext (); | |||
381 | } | |||
382 | ||||
383 | uint32_t | |||
384 | Simulator::GetSystemId (void) | |||
385 | { | |||
386 | NS_LOG_FUNCTION_NOARGS ()do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "()" << std::endl; } } while (false ); | |||
387 | ||||
388 | if (*PeekImpl () != 0) | |||
389 | { | |||
390 | return GetImpl ()->GetSystemId (); | |||
391 | } | |||
392 | else | |||
393 | { | |||
394 | return 0; | |||
395 | } | |||
396 | } | |||
397 | ||||
398 | void | |||
399 | Simulator::SetImplementation (Ptr<SimulatorImpl> impl) | |||
400 | { | |||
401 | NS_LOG_FUNCTION (impl)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << impl; std::clog << ")" << std::endl; } } while ( false); | |||
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.")do { std::cerr << "msg=\"" << "It is not possible to set the implementation after calling any Simulator:: function. Call Simulator::SetImplementation earlier or after Simulator::Destroy." << "\", "; do { std::cerr << "file=" << "../src/core/model/simulator.cc" << ", line=" << 404 << std::endl; ::ns3::FatalImpl ::FlushStreams (); if (true) std::terminate (); } while (false ); } while (false); | |||
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 | // | |||
420 | LogSetTimePrinter (&TimePrinter); | |||
421 | LogSetNodePrinter (&NodePrinter); | |||
422 | } | |||
423 | ||||
424 | Ptr<SimulatorImpl> | |||
425 | Simulator::GetImplementation (void) | |||
426 | { | |||
427 | NS_LOG_FUNCTION_NOARGS ()do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "()" << std::endl; } } while (false ); | |||
428 | return GetImpl (); | |||
429 | } | |||
430 | ||||
431 | ||||
432 | ||||
433 | } // namespace ns3 | |||
434 |