19 #include "distributed-simulator-impl.h"
20 #include "mpi-interface.h"
22 #include "ns3/simulator.h"
23 #include "ns3/scheduler.h"
24 #include "ns3/event-impl.h"
25 #include "ns3/channel.h"
26 #include "ns3/node-container.h"
28 #include "ns3/pointer.h"
29 #include "ns3/assert.h"
42 NS_OBJECT_ENSURE_REGISTERED (DistributedSimulatorImpl);
44 LbtsMessage::~LbtsMessage ()
51 return m_smallestTime;
71 Time DistributedSimulatorImpl::m_lookAhead =
Seconds (0);
74 DistributedSimulatorImpl::GetTypeId (
void)
76 static TypeId tid =
TypeId (
"ns3::DistributedSimulatorImpl")
78 .AddConstructor<DistributedSimulatorImpl> ()
83 DistributedSimulatorImpl::DistributedSimulatorImpl ()
90 m_pLBTS =
new LbtsMessage[m_systemCount];
93 NS_FATAL_ERROR (
"Can't use distributed simulator without MPI compiled in");
105 m_currentContext = 0xffffffff;
106 m_unscheduledEvents = 0;
110 DistributedSimulatorImpl::~DistributedSimulatorImpl ()
117 while (!m_events->IsEmpty ())
130 while (!m_destroyEvents.empty ())
133 m_destroyEvents.pop_front ();
135 if (!ev->IsCancelled ())
146 DistributedSimulatorImpl::CalculateLookAhead (
void)
151 DistributedSimulatorImpl::m_lookAhead =
Seconds (0);
157 for (NodeContainer::Iterator iter = c.Begin (); iter != c.End (); ++iter)
164 for (uint32_t i = 0; i < (*iter)->GetNDevices (); ++i)
166 Ptr<NetDevice> localNetDevice = (*iter)->GetDevice (i);
168 if (!localNetDevice->IsPointToPoint ())
172 Ptr<Channel> channel = localNetDevice->GetChannel ();
179 Ptr<Node> remoteNode;
180 if (channel->GetDevice (0) == localNetDevice)
182 remoteNode = (channel->GetDevice (1))->GetNode ();
186 remoteNode = (channel->GetDevice (0))->GetNode ();
199 channel->GetAttribute (
"Delay", delay);
200 if (DistributedSimulatorImpl::m_lookAhead.IsZero ())
202 DistributedSimulatorImpl::m_lookAhead = delay.Get ();
203 m_grantedTime = delay.Get ();
205 if (delay.Get ().GetSeconds () < DistributedSimulatorImpl::m_lookAhead.GetSeconds ())
207 DistributedSimulatorImpl::m_lookAhead = delay.Get ();
208 m_grantedTime = delay.Get ();
214 NS_FATAL_ERROR (
"Can't use distributed simulator without MPI compiled in");
225 while (!m_events->IsEmpty ())
228 scheduler->Insert (next);
231 m_events = scheduler;
235 DistributedSimulatorImpl::ProcessOneEvent (
void)
239 NS_ASSERT (next.key.m_ts >= m_currentTs);
240 m_unscheduledEvents--;
243 m_currentTs = next.key.m_ts;
244 m_currentContext = next.key.m_context;
245 m_currentUid = next.key.m_uid;
253 return m_events->IsEmpty () || m_stop;
257 DistributedSimulatorImpl::NextTs (
void)
const
265 DistributedSimulatorImpl::Next (
void)
const
267 return TimeStep (NextTs ());
274 CalculateLookAhead ();
276 while (!m_events->IsEmpty () && !m_stop)
278 Time nextTime = Next ();
279 if (nextTime > m_grantedTime)
289 m_pLBTS[m_myId] = lMsg;
290 MPI_Allgather (&lMsg,
sizeof (
LbtsMessage), MPI_BYTE, m_pLBTS,
299 for (uint32_t i = 1; i < m_systemCount; ++i)
301 if (m_pLBTS[i].GetSmallestTime () < smallestTime)
311 m_grantedTime = smallestTime + DistributedSimulatorImpl::m_lookAhead;
314 if (nextTime <= m_grantedTime)
322 NS_ASSERT (!m_events->IsEmpty () || m_unscheduledEvents == 0);
324 NS_FATAL_ERROR (
"Can't use distributed simulator without MPI compiled in");
351 Time tAbsolute = time + TimeStep (m_currentTs);
354 NS_ASSERT (tAbsolute >= TimeStep (m_currentTs));
357 ev.key.m_ts =
static_cast<uint64_t
> (tAbsolute.
GetTimeStep ());
359 ev.key.m_uid = m_uid;
361 m_unscheduledEvents++;
362 m_events->Insert (ev);
363 return EventId (event, ev.key.m_ts, ev.key.m_context, ev.key.m_uid);
374 ev.key.m_context = context;
375 ev.key.m_uid = m_uid;
377 m_unscheduledEvents++;
378 m_events->Insert (ev);
386 ev.key.m_ts = m_currentTs;
388 ev.key.m_uid = m_uid;
390 m_unscheduledEvents++;
391 m_events->Insert (ev);
392 return EventId (event, ev.key.m_ts, ev.key.m_context, ev.key.m_uid);
399 m_destroyEvents.push_back (
id);
407 return TimeStep (m_currentTs);
419 return TimeStep (
id.GetTs () - m_currentTs);
426 if (
id.GetUid () == 2)
429 for (DestroyEvents::iterator i = m_destroyEvents.begin (); i != m_destroyEvents.end (); i++)
433 m_destroyEvents.erase (i);
444 event.impl =
id.PeekEventImpl ();
445 event.key.m_ts =
id.GetTs ();
446 event.key.m_context =
id.GetContext ();
447 event.key.m_uid =
id.GetUid ();
448 m_events->Remove (event);
449 event.impl->Cancel ();
451 event.impl->Unref ();
453 m_unscheduledEvents--;
461 id.PeekEventImpl ()->Cancel ();
468 if (ev.GetUid () == 2)
470 if (ev.PeekEventImpl () == 0
476 for (DestroyEvents::const_iterator i = m_destroyEvents.begin (); i != m_destroyEvents.end (); i++)
485 if (ev.PeekEventImpl () == 0
486 || ev.GetTs () < m_currentTs
487 || (ev.GetTs () == m_currentTs
488 && ev.GetUid () <= m_currentUid)
504 return TimeStep (0x7fffffffffffffffLL);
510 return m_currentContext;
smart pointer class similar to boost::intrusive_ptr
bool IsPositive(void) const
#define NS_LOG_FUNCTION(parameters)
virtual void SetScheduler(ObjectFactory schedulerFactory)
#define NS_ASSERT(condition)
#define NS_LOG_COMPONENT_DEFINE(name)
virtual EventId ScheduleDestroy(EventImpl *event)
virtual Time GetMaximumSimulationTime(void) const
virtual void DoDispose(void)
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
virtual Time Now(void) const
#define NS_FATAL_ERROR(msg)
fatal error handling
virtual void DoDispose(void)
static uint32_t GetTxCount()
virtual Time GetDelayLeft(const EventId &id) const
Ptr< Object > Create(void) const
virtual EventId ScheduleNow(EventImpl *event)
static uint32_t GetRxCount()
static void ReceiveMessages()
static void TestSendComplete()
#define NS_LOG_LOGIC(msg)
virtual void Remove(const EventId &ev)
virtual void ScheduleWithContext(uint32_t context, Time const &time, EventImpl *event)
int64_t GetTimeStep(void) const
virtual uint32_t GetSystemId(void) const
virtual uint32_t GetContext(void) const
Structure used for all-reduce LBTS computation.
static NodeContainer GetGlobal(void)
Create a NodeContainer that contains a list of all nodes created through NodeContainer::Create() and ...
virtual void Cancel(const EventId &ev)
instantiate subclasses of ns3::Object.
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
virtual EventId Schedule(Time const &time, EventImpl *event)
an identifier for simulation events.
static uint32_t GetSystemId()
a base class which provides memory management and object aggregation
virtual bool IsFinished(void) const
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
static uint32_t GetSize()
virtual bool IsExpired(const EventId &ev) const