|
|
| 68 |
NS_LOG_FUNCTION_NOARGS (); |
68 |
NS_LOG_FUNCTION_NOARGS (); |
| 69 |
|
69 |
|
| 70 |
m_stop = false; |
70 |
m_stop = false; |
| 71 |
m_stopAt = 0; |
|
|
| 72 |
m_running = false; |
71 |
m_running = false; |
| 73 |
// uids are allocated from 4. |
72 |
// uids are allocated from 4. |
| 74 |
// uid 0 is "invalid" events |
73 |
// uid 0 is "invalid" events |
|
|
| 441 |
{ |
440 |
{ |
| 442 |
done = true; |
441 |
done = true; |
| 443 |
} |
442 |
} |
| 444 |
// |
|
|
| 445 |
// We also want to stop the simulator at some time even if there are events |
| 446 |
// that have been scheduled out in the future. If we're in realtime mode, we |
| 447 |
// actually have time passing, so we must look at the realtime clock to see if |
| 448 |
// we're past the end time. |
| 449 |
// |
| 450 |
if (m_stopAt && m_stopAt <= m_synchronizer->GetCurrentRealtime ()) |
| 451 |
{ |
| 452 |
done = true; |
| 453 |
} |
| 454 |
} |
443 |
} |
| 455 |
|
444 |
|
| 456 |
if (done) |
445 |
if (done) |
|
|
| 537 |
{ |
526 |
{ |
| 538 |
NS_LOG_FUNCTION_NOARGS (); |
527 |
NS_LOG_FUNCTION_NOARGS (); |
| 539 |
m_stop = true; |
528 |
m_stop = true; |
| 540 |
} |
|
|
| 541 |
|
| 542 |
static void Placeholder (void) {} |
| 543 |
|
| 544 |
// |
| 545 |
// Schedule a stop for a _relative_ time in the future. If the simulation |
| 546 |
// hasn't started yet, this will effectively be an absolute time. |
| 547 |
// |
| 548 |
void |
| 549 |
RealtimeSimulatorImpl::Stop (Time const &time) |
| 550 |
{ |
| 551 |
NS_LOG_FUNCTION (time); |
| 552 |
|
| 553 |
Time tAbsolute = Simulator::Now () + time; |
| 554 |
NS_ASSERT (tAbsolute.IsPositive ()); |
| 555 |
NS_ASSERT (tAbsolute >= TimeStep (m_currentTs)); |
| 556 |
m_stopAt = tAbsolute.GetTimeStep (); |
| 557 |
|
| 558 |
// |
| 559 |
// For the realtime case, we need a real event sitting out at the end of time |
| 560 |
// to keep the simulator running (sleeping) while there are no other events |
| 561 |
// present. If an "external" device in another thread decides to schedule an |
| 562 |
// event, the sleeping synchronizer will be awakened and the new event will |
| 563 |
// be run. |
| 564 |
// |
| 565 |
// The easiest thing to do is to call back up into the simulator to take |
| 566 |
// advantage of all of the nice event wrappers. This will call back down into |
| 567 |
// RealtimeSimulatorImpl::Schedule to do the work. This path interprets the |
| 568 |
// time as relative, so pass the relative time. |
| 569 |
// |
| 570 |
Simulator::Schedule (time, &Placeholder); |
| 571 |
} |
529 |
} |
| 572 |
|
530 |
|
| 573 |
// |
531 |
// |