Introduce Simulator::ScheduleWithContext* and Simulator::GetContext
This commit is contained in:
@@ -36,6 +36,9 @@ class NetDevice;
|
||||
*
|
||||
* A channel is a logical path over which information flows. The path can
|
||||
* be as simple as a short piece of wire, or as complicated as space-time.
|
||||
*
|
||||
* Subclasses must use Simulator::ScheduleWithContext to correctly update
|
||||
* event contexts when scheduling an event from one node to another one.
|
||||
*/
|
||||
class Channel : public Object
|
||||
{
|
||||
|
||||
@@ -53,10 +53,11 @@ DefaultSimulatorImpl::DefaultSimulatorImpl ()
|
||||
// uid 0 is "invalid" events
|
||||
// uid 1 is "now" events
|
||||
// uid 2 is "destroy" events
|
||||
m_uid = 4;
|
||||
m_uid = 4;
|
||||
// before ::Run is entered, the m_currentUid will be zero
|
||||
m_currentUid = 0;
|
||||
m_currentTs = 0;
|
||||
m_currentContext = 0xffffffff;
|
||||
m_unscheduledEvents = 0;
|
||||
}
|
||||
|
||||
@@ -107,10 +108,11 @@ DefaultSimulatorImpl::ProcessOneEvent (void)
|
||||
Scheduler::Event next = m_events->RemoveNext ();
|
||||
|
||||
NS_ASSERT (next.key.m_ts >= m_currentTs);
|
||||
--m_unscheduledEvents;
|
||||
m_unscheduledEvents--;
|
||||
|
||||
NS_LOG_LOGIC ("handle " << next.key.m_ts);
|
||||
m_currentTs = next.key.m_ts;
|
||||
m_currentContext = next.key.m_context;
|
||||
m_currentUid = next.key.m_uid;
|
||||
next.impl->Invoke ();
|
||||
next.impl->Unref ();
|
||||
@@ -162,6 +164,11 @@ DefaultSimulatorImpl::Stop (void)
|
||||
m_stop = true;
|
||||
}
|
||||
|
||||
void
|
||||
DefaultSimulatorImpl::Stop (Time const &time)
|
||||
{
|
||||
Simulator::Schedule (time, &Simulator::Stop);
|
||||
}
|
||||
|
||||
//
|
||||
// Schedule an event for a _relative_ time in the future.
|
||||
@@ -169,18 +176,34 @@ DefaultSimulatorImpl::Stop (void)
|
||||
EventId
|
||||
DefaultSimulatorImpl::Schedule (Time const &time, EventImpl *event)
|
||||
{
|
||||
Time tAbsolute = time + Now();
|
||||
Time tAbsolute = time + TimeStep (m_currentTs);
|
||||
|
||||
NS_ASSERT (tAbsolute.IsPositive ());
|
||||
NS_ASSERT (tAbsolute >= TimeStep (m_currentTs));
|
||||
Scheduler::Event ev;
|
||||
ev.impl = event;
|
||||
ev.key.m_ts = (uint64_t) tAbsolute.GetTimeStep ();
|
||||
ev.key.m_context = GetContext ();
|
||||
ev.key.m_uid = m_uid;
|
||||
m_uid++;
|
||||
++m_unscheduledEvents;
|
||||
m_unscheduledEvents++;
|
||||
m_events->Insert (ev);
|
||||
return EventId (event, ev.key.m_ts, ev.key.m_context, ev.key.m_uid);
|
||||
}
|
||||
|
||||
void
|
||||
DefaultSimulatorImpl::ScheduleWithContext (uint32_t context, Time const &time, EventImpl *event)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << context << time.GetTimeStep () << m_currentTs << event);
|
||||
|
||||
Scheduler::Event ev;
|
||||
ev.impl = event;
|
||||
ev.key.m_ts = m_currentTs + time.GetTimeStep ();
|
||||
ev.key.m_context = context;
|
||||
ev.key.m_uid = m_uid;
|
||||
m_uid++;
|
||||
m_unscheduledEvents++;
|
||||
m_events->Insert (ev);
|
||||
return EventId (event, ev.key.m_ts, ev.key.m_uid);
|
||||
}
|
||||
|
||||
EventId
|
||||
@@ -189,17 +212,18 @@ DefaultSimulatorImpl::ScheduleNow (EventImpl *event)
|
||||
Scheduler::Event ev;
|
||||
ev.impl = event;
|
||||
ev.key.m_ts = m_currentTs;
|
||||
ev.key.m_context = GetContext ();
|
||||
ev.key.m_uid = m_uid;
|
||||
m_uid++;
|
||||
++m_unscheduledEvents;
|
||||
m_unscheduledEvents++;
|
||||
m_events->Insert (ev);
|
||||
return EventId (event, ev.key.m_ts, ev.key.m_uid);
|
||||
return EventId (event, ev.key.m_ts, ev.key.m_context, ev.key.m_uid);
|
||||
}
|
||||
|
||||
EventId
|
||||
DefaultSimulatorImpl::ScheduleDestroy (EventImpl *event)
|
||||
{
|
||||
EventId id (Ptr<EventImpl> (event, false), m_currentTs, 2);
|
||||
EventId id (Ptr<EventImpl> (event, false), m_currentTs, 0xffffffff, 2);
|
||||
m_destroyEvents.push_back (id);
|
||||
m_uid++;
|
||||
return id;
|
||||
@@ -247,13 +271,14 @@ DefaultSimulatorImpl::Remove (const EventId &id)
|
||||
Scheduler::Event event;
|
||||
event.impl = id.PeekEventImpl ();
|
||||
event.key.m_ts = id.GetTs ();
|
||||
event.key.m_context = id.GetContext ();
|
||||
event.key.m_uid = id.GetUid ();
|
||||
m_events->Remove (event);
|
||||
event.impl->Cancel ();
|
||||
// whenever we remove an event from the event list, we have to unref it.
|
||||
event.impl->Unref ();
|
||||
|
||||
--m_unscheduledEvents;
|
||||
m_unscheduledEvents--;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -307,6 +332,12 @@ DefaultSimulatorImpl::GetMaximumSimulationTime (void) const
|
||||
return TimeStep (0x7fffffffffffffffLL);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
DefaultSimulatorImpl::GetContext (void) const
|
||||
{
|
||||
return m_currentContext;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
|
||||
@@ -26,14 +26,12 @@
|
||||
#include "event-impl.h"
|
||||
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/assert.h"
|
||||
#include "ns3/log.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class DefaultSimulatorImpl : public SimulatorImpl
|
||||
class DefaultSimulatorImpl : public SimulatorImpl
|
||||
{
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
@@ -45,7 +43,9 @@ public:
|
||||
virtual bool IsFinished (void) const;
|
||||
virtual Time Next (void) const;
|
||||
virtual void Stop (void);
|
||||
virtual void Stop (Time const &time);
|
||||
virtual EventId Schedule (Time const &time, EventImpl *event);
|
||||
virtual void ScheduleWithContext (uint32_t context, Time const &time, EventImpl *event);
|
||||
virtual EventId ScheduleNow (EventImpl *event);
|
||||
virtual EventId ScheduleDestroy (EventImpl *event);
|
||||
virtual void Remove (const EventId &ev);
|
||||
@@ -57,18 +57,20 @@ public:
|
||||
virtual Time GetDelayLeft (const EventId &id) const;
|
||||
virtual Time GetMaximumSimulationTime (void) const;
|
||||
virtual void SetScheduler (ObjectFactory schedulerFactory);
|
||||
virtual uint32_t GetContext (void) const;
|
||||
|
||||
private:
|
||||
void ProcessOneEvent (void);
|
||||
uint64_t NextTs (void) const;
|
||||
|
||||
typedef std::list<EventId> DestroyEvents;
|
||||
|
||||
DestroyEvents m_destroyEvents;
|
||||
bool m_stop;
|
||||
Ptr<Scheduler> m_events;
|
||||
uint32_t m_uid;
|
||||
uint32_t m_currentUid;
|
||||
uint64_t m_currentTs;
|
||||
uint32_t m_currentContext;
|
||||
// number of events that have been inserted but not yet scheduled,
|
||||
// not counting the "destroy" events; this is used for validation
|
||||
int m_unscheduledEvents;
|
||||
|
||||
@@ -26,12 +26,14 @@ namespace ns3 {
|
||||
EventId::EventId ()
|
||||
: m_eventImpl (0),
|
||||
m_ts (0),
|
||||
m_context (0),
|
||||
m_uid (0)
|
||||
{}
|
||||
|
||||
EventId::EventId (const Ptr<EventImpl> &impl, uint64_t ts, uint32_t uid)
|
||||
EventId::EventId (const Ptr<EventImpl> &impl, uint64_t ts, uint32_t context, uint32_t uid)
|
||||
: m_eventImpl (impl),
|
||||
m_ts (ts),
|
||||
m_context (context),
|
||||
m_uid (uid)
|
||||
{}
|
||||
void
|
||||
@@ -60,6 +62,11 @@ EventId::GetTs (void) const
|
||||
return m_ts;
|
||||
}
|
||||
uint32_t
|
||||
EventId::GetContext (void) const
|
||||
{
|
||||
return m_context;
|
||||
}
|
||||
uint32_t
|
||||
EventId::GetUid (void) const
|
||||
{
|
||||
return m_uid;
|
||||
@@ -69,6 +76,7 @@ bool operator == (const EventId &a, const EventId &b)
|
||||
{
|
||||
return
|
||||
a.m_uid == b.m_uid &&
|
||||
a.m_context == b.m_context &&
|
||||
a.m_ts == b.m_ts &&
|
||||
a.m_eventImpl == b.m_eventImpl;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ class EventId {
|
||||
public:
|
||||
EventId ();
|
||||
// internal.
|
||||
EventId (const Ptr<EventImpl> &impl, uint64_t ts, uint32_t uid);
|
||||
EventId (const Ptr<EventImpl> &impl, uint64_t ts, uint32_t context, uint32_t uid);
|
||||
/**
|
||||
* This method is syntactic sugar for the ns3::Simulator::cancel
|
||||
* method.
|
||||
@@ -72,11 +72,13 @@ public:
|
||||
*/
|
||||
EventImpl *PeekEventImpl (void) const;
|
||||
uint64_t GetTs (void) const;
|
||||
uint32_t GetContext (void) const;
|
||||
uint32_t GetUid (void) const;
|
||||
private:
|
||||
friend bool operator == (const EventId &a, const EventId &b);
|
||||
Ptr<EventImpl> m_eventImpl;
|
||||
uint64_t m_ts;
|
||||
uint32_t m_context;
|
||||
uint32_t m_uid;
|
||||
};
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ RealtimeSimulatorImpl::RealtimeSimulatorImpl ()
|
||||
// before ::Run is entered, the m_currentUid will be zero
|
||||
m_currentUid = 0;
|
||||
m_currentTs = 0;
|
||||
m_currentContext = 0xffffffff;
|
||||
m_unscheduledEvents = 0;
|
||||
|
||||
// Be very careful not to do anything that would cause a change or assignment
|
||||
@@ -309,7 +310,7 @@ RealtimeSimulatorImpl::ProcessOneEvent (void)
|
||||
NS_ASSERT_MSG (m_events->IsEmpty () == false,
|
||||
"RealtimeSimulatorImpl::ProcessOneEvent(): event queue is empty");
|
||||
next = m_events->RemoveNext ();
|
||||
--m_unscheduledEvents;
|
||||
m_unscheduledEvents--;
|
||||
|
||||
//
|
||||
// We cannot make any assumption that "next" is the same event we originally waited
|
||||
@@ -327,6 +328,7 @@ RealtimeSimulatorImpl::ProcessOneEvent (void)
|
||||
// is frozen until the next event is executed.
|
||||
//
|
||||
m_currentTs = next.key.m_ts;
|
||||
m_currentContext = next.key.m_context;
|
||||
m_currentUid = next.key.m_uid;
|
||||
|
||||
//
|
||||
@@ -506,10 +508,11 @@ RealtimeSimulatorImpl::RunOneEvent (void)
|
||||
Scheduler::Event next = m_events->RemoveNext ();
|
||||
|
||||
NS_ASSERT (next.key.m_ts >= m_currentTs);
|
||||
--m_unscheduledEvents;
|
||||
m_unscheduledEvents--;
|
||||
|
||||
NS_LOG_LOGIC ("handle " << next.key.m_ts);
|
||||
m_currentTs = next.key.m_ts;
|
||||
m_currentContext = next.key.m_context;
|
||||
m_currentUid = next.key.m_ts;
|
||||
event = next.impl;
|
||||
}
|
||||
@@ -524,6 +527,12 @@ RealtimeSimulatorImpl::Stop (void)
|
||||
m_stop = true;
|
||||
}
|
||||
|
||||
void
|
||||
RealtimeSimulatorImpl::Stop (Time const &time)
|
||||
{
|
||||
Simulator::Schedule (time, &Simulator::Stop);
|
||||
}
|
||||
|
||||
//
|
||||
// Schedule an event for a _relative_ time in the future.
|
||||
//
|
||||
@@ -546,14 +555,38 @@ RealtimeSimulatorImpl::Schedule (Time const &time, EventImpl *impl)
|
||||
NS_ASSERT_MSG (tAbsolute >= TimeStep (m_currentTs), "RealtimeSimulatorImpl::Schedule(): time < m_currentTs");
|
||||
ev.impl = impl;
|
||||
ev.key.m_ts = (uint64_t) tAbsolute.GetTimeStep ();
|
||||
ev.key.m_context = GetContext ();
|
||||
ev.key.m_uid = m_uid;
|
||||
m_uid++;
|
||||
++m_unscheduledEvents;
|
||||
m_unscheduledEvents++;
|
||||
m_events->Insert (ev);
|
||||
m_synchronizer->Signal ();
|
||||
}
|
||||
|
||||
return EventId (impl, ev.key.m_ts, ev.key.m_uid);
|
||||
return EventId (impl, ev.key.m_ts, ev.key.m_context, ev.key.m_uid);
|
||||
}
|
||||
|
||||
void
|
||||
RealtimeSimulatorImpl::ScheduleWithContext (uint32_t context, Time const &time, EventImpl *impl)
|
||||
{
|
||||
NS_LOG_FUNCTION (time << impl);
|
||||
|
||||
{
|
||||
CriticalSection cs (m_mutex);
|
||||
uint64_t ts;
|
||||
|
||||
ts = m_currentTs + time.GetTimeStep ();
|
||||
NS_ASSERT_MSG (ts >= m_currentTs, "RealtimeSimulatorImpl::ScheduleRealtime(): schedule for time < m_currentTs");
|
||||
Scheduler::Event ev;
|
||||
ev.impl = impl;
|
||||
ev.key.m_ts = ts;
|
||||
ev.key.m_context = context;
|
||||
ev.key.m_uid = m_uid;
|
||||
m_uid++;
|
||||
m_unscheduledEvents++;
|
||||
m_events->Insert (ev);
|
||||
m_synchronizer->Signal ();
|
||||
}
|
||||
}
|
||||
|
||||
EventId
|
||||
@@ -566,14 +599,15 @@ RealtimeSimulatorImpl::ScheduleNow (EventImpl *impl)
|
||||
|
||||
ev.impl = impl;
|
||||
ev.key.m_ts = m_currentTs;
|
||||
ev.key.m_context = GetContext ();
|
||||
ev.key.m_uid = m_uid;
|
||||
m_uid++;
|
||||
++m_unscheduledEvents;
|
||||
m_unscheduledEvents++;
|
||||
m_events->Insert (ev);
|
||||
m_synchronizer->Signal ();
|
||||
}
|
||||
|
||||
return EventId (impl, ev.key.m_ts, ev.key.m_uid);
|
||||
return EventId (impl, ev.key.m_ts, ev.key.m_context, ev.key.m_uid);
|
||||
}
|
||||
|
||||
Time
|
||||
@@ -601,7 +635,7 @@ RealtimeSimulatorImpl::ScheduleRealtime (Time const &time, EventImpl *impl)
|
||||
ev.key.m_ts = ts;
|
||||
ev.key.m_uid = m_uid;
|
||||
m_uid++;
|
||||
++m_unscheduledEvents;
|
||||
m_unscheduledEvents++;
|
||||
m_events->Insert (ev);
|
||||
m_synchronizer->Signal ();
|
||||
}
|
||||
@@ -626,7 +660,7 @@ RealtimeSimulatorImpl::ScheduleRealtimeNow (EventImpl *impl)
|
||||
ev.key.m_ts = ts;
|
||||
ev.key.m_uid = m_uid;
|
||||
m_uid++;
|
||||
++m_unscheduledEvents;
|
||||
m_unscheduledEvents++;
|
||||
m_events->Insert (ev);
|
||||
m_synchronizer->Signal ();
|
||||
}
|
||||
@@ -652,7 +686,7 @@ RealtimeSimulatorImpl::ScheduleDestroy (EventImpl *impl)
|
||||
// overridden by the uid of 2 which identifies this as an event to be
|
||||
// executed at Simulator::Destroy time.
|
||||
//
|
||||
id = EventId (Ptr<EventImpl> (impl, false), m_currentTs, 2);
|
||||
id = EventId (Ptr<EventImpl> (impl, false), m_currentTs, 0xffffffff, 2);
|
||||
m_destroyEvents.push_back (id);
|
||||
m_uid++;
|
||||
}
|
||||
@@ -704,10 +738,11 @@ RealtimeSimulatorImpl::Remove (const EventId &id)
|
||||
Scheduler::Event event;
|
||||
event.impl = id.PeekEventImpl ();
|
||||
event.key.m_ts = id.GetTs ();
|
||||
event.key.m_context = id.GetContext ();
|
||||
event.key.m_uid = id.GetUid ();
|
||||
|
||||
m_events->Remove (event);
|
||||
--m_unscheduledEvents;
|
||||
m_unscheduledEvents--;
|
||||
event.impl->Cancel ();
|
||||
event.impl->Unref ();
|
||||
}
|
||||
@@ -773,6 +808,12 @@ RealtimeSimulatorImpl::GetMaximumSimulationTime (void) const
|
||||
return TimeStep (0x7fffffffffffffffLL);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
RealtimeSimulatorImpl::GetContext (void) const
|
||||
{
|
||||
return m_currentContext;
|
||||
}
|
||||
|
||||
void
|
||||
RealtimeSimulatorImpl::SetSynchronizationMode (enum SynchronizationMode mode)
|
||||
{
|
||||
|
||||
@@ -55,7 +55,9 @@ public:
|
||||
virtual bool IsFinished (void) const;
|
||||
virtual Time Next (void) const;
|
||||
virtual void Stop (void);
|
||||
virtual void Stop (Time const &time);
|
||||
virtual EventId Schedule (Time const &time, EventImpl *event);
|
||||
virtual void ScheduleWithContext (uint32_t context, Time const &time, EventImpl *event);
|
||||
virtual EventId ScheduleNow (EventImpl *event);
|
||||
virtual EventId ScheduleDestroy (EventImpl *event);
|
||||
virtual void Remove (const EventId &ev);
|
||||
@@ -67,6 +69,7 @@ public:
|
||||
virtual Time GetDelayLeft (const EventId &id) const;
|
||||
virtual Time GetMaximumSimulationTime (void) const;
|
||||
virtual void SetScheduler (ObjectFactory schedulerFactory);
|
||||
virtual uint32_t GetContext (void) const;
|
||||
|
||||
void ScheduleRealtime (Time const &time, EventImpl *event);
|
||||
void ScheduleRealtimeNow (EventImpl *event);
|
||||
@@ -96,6 +99,7 @@ private:
|
||||
uint32_t m_uid;
|
||||
uint32_t m_currentUid;
|
||||
uint64_t m_currentTs;
|
||||
uint32_t m_currentContext;
|
||||
|
||||
mutable SystemMutex m_mutex;
|
||||
|
||||
|
||||
@@ -56,8 +56,9 @@ class Scheduler : public Object
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
struct EventKey {
|
||||
uint64_t m_ts;
|
||||
uint32_t m_uid;
|
||||
uint64_t m_ts;
|
||||
uint32_t m_uid;
|
||||
uint32_t m_context;
|
||||
};
|
||||
struct Event {
|
||||
EventImpl *impl;
|
||||
|
||||
@@ -39,7 +39,9 @@ public:
|
||||
virtual bool IsFinished (void) const = 0;
|
||||
virtual Time Next (void) const = 0;
|
||||
virtual void Stop (void) = 0;
|
||||
virtual void Stop (Time const &time) = 0;
|
||||
virtual EventId Schedule (Time const &time, EventImpl *event) = 0;
|
||||
virtual void ScheduleWithContext (uint32_t context, Time const &time, EventImpl *event) = 0;
|
||||
virtual EventId ScheduleNow (EventImpl *event) = 0;
|
||||
virtual EventId ScheduleDestroy (EventImpl *event) = 0;
|
||||
virtual void Remove (const EventId &ev) = 0;
|
||||
@@ -51,6 +53,7 @@ public:
|
||||
virtual Time GetDelayLeft (const EventId &id) const = 0;
|
||||
virtual Time GetMaximumSimulationTime (void) const = 0;
|
||||
virtual void SetScheduler (ObjectFactory schedulerFactory) = 0;
|
||||
virtual uint32_t GetContext (void) const = 0;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -20,10 +20,6 @@
|
||||
#include "ns3/core-config.h"
|
||||
#include "simulator.h"
|
||||
#include "simulator-impl.h"
|
||||
#include "default-simulator-impl.h"
|
||||
#ifdef HAVE_PTHREAD_H
|
||||
# include "realtime-simulator-impl.h"
|
||||
#endif
|
||||
#include "scheduler.h"
|
||||
#include "map-scheduler.h"
|
||||
#include "event-impl.h"
|
||||
@@ -71,19 +67,19 @@ TimePrinter (std::ostream &os)
|
||||
|
||||
#endif /* NS3_LOG_ENABLE */
|
||||
|
||||
static Ptr<SimulatorImpl> *PeekImpl (void)
|
||||
static SimulatorImpl **PeekImpl (void)
|
||||
{
|
||||
static Ptr<SimulatorImpl> impl = 0;
|
||||
static SimulatorImpl *impl = 0;
|
||||
return &impl;
|
||||
}
|
||||
|
||||
static SimulatorImpl * GetImpl (void)
|
||||
{
|
||||
Ptr<SimulatorImpl> &impl = *PeekImpl ();
|
||||
SimulatorImpl **pimpl = PeekImpl ();
|
||||
/* Please, don't include any calls to logging macros in this function
|
||||
* or pay the price, that is, stack explosions.
|
||||
*/
|
||||
if (impl == 0)
|
||||
if (*pimpl == 0)
|
||||
{
|
||||
{
|
||||
ObjectFactory factory;
|
||||
@@ -91,14 +87,14 @@ static SimulatorImpl * GetImpl (void)
|
||||
|
||||
g_simTypeImpl.GetValue (s);
|
||||
factory.SetTypeId (s.Get ());
|
||||
impl = factory.Create<SimulatorImpl> ();
|
||||
*pimpl = GetPointer (factory.Create<SimulatorImpl> ());
|
||||
}
|
||||
{
|
||||
ObjectFactory factory;
|
||||
StringValue s;
|
||||
g_schedTypeImpl.GetValue (s);
|
||||
factory.SetTypeId (s.Get ());
|
||||
impl->SetScheduler (factory);
|
||||
(*pimpl)->SetScheduler (factory);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -110,7 +106,7 @@ static SimulatorImpl * GetImpl (void)
|
||||
//
|
||||
LogSetTimePrinter (&TimePrinter);
|
||||
}
|
||||
return PeekPointer (impl);
|
||||
return *pimpl;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -118,8 +114,8 @@ Simulator::Destroy (void)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
|
||||
Ptr<SimulatorImpl> &impl = *PeekImpl ();
|
||||
if (impl == 0)
|
||||
SimulatorImpl **pimpl = PeekImpl ();
|
||||
if (*pimpl == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -129,8 +125,9 @@ Simulator::Destroy (void)
|
||||
* the stack explodes.
|
||||
*/
|
||||
LogSetTimePrinter (0);
|
||||
impl->Destroy ();
|
||||
impl = 0;
|
||||
(*pimpl)->Destroy ();
|
||||
(*pimpl)->Unref ();
|
||||
*pimpl = 0;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -179,7 +176,7 @@ void
|
||||
Simulator::Stop (Time const &time)
|
||||
{
|
||||
NS_LOG_FUNCTION (time);
|
||||
Simulator::Schedule (time, &Simulator::Stop);
|
||||
GetImpl ()->Stop (time);
|
||||
}
|
||||
|
||||
Time
|
||||
@@ -205,6 +202,13 @@ Simulator::Schedule (Time const &time, const Ptr<EventImpl> &ev)
|
||||
return DoSchedule (time, GetPointer (ev));
|
||||
}
|
||||
|
||||
void
|
||||
Simulator::ScheduleWithContext (uint32_t context, Time const &time, const Ptr<EventImpl> &ev)
|
||||
{
|
||||
NS_LOG_FUNCTION (time << context << ev);
|
||||
return DoScheduleWithContext (context, time, GetPointer (ev));
|
||||
}
|
||||
|
||||
EventId
|
||||
Simulator::ScheduleNow (const Ptr<EventImpl> &ev)
|
||||
{
|
||||
@@ -223,6 +227,11 @@ Simulator::DoSchedule (Time const &time, EventImpl *impl)
|
||||
{
|
||||
return GetImpl ()->Schedule (time, impl);
|
||||
}
|
||||
void
|
||||
Simulator::DoScheduleWithContext (uint32_t context, Time const &time, EventImpl *impl)
|
||||
{
|
||||
return GetImpl ()->ScheduleWithContext (context, time, impl);
|
||||
}
|
||||
EventId
|
||||
Simulator::DoScheduleNow (EventImpl *impl)
|
||||
{
|
||||
@@ -242,6 +251,13 @@ Simulator::Schedule (Time const &time, void (*f) (void))
|
||||
return DoSchedule (time, MakeEvent (f));
|
||||
}
|
||||
|
||||
void
|
||||
Simulator::ScheduleWithContext (uint32_t context, Time const &time, void (*f) (void))
|
||||
{
|
||||
NS_LOG_FUNCTION (time << context << f);
|
||||
return DoScheduleWithContext (context, time, MakeEvent (f));
|
||||
}
|
||||
|
||||
EventId
|
||||
Simulator::ScheduleNow (void (*f) (void))
|
||||
{
|
||||
@@ -290,6 +306,13 @@ Simulator::GetMaximumSimulationTime (void)
|
||||
return GetImpl ()->GetMaximumSimulationTime ();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Simulator::GetContext (void)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
return GetImpl ()->GetContext ();
|
||||
}
|
||||
|
||||
void
|
||||
Simulator::SetImplementation (Ptr<SimulatorImpl> impl)
|
||||
{
|
||||
@@ -297,7 +320,7 @@ Simulator::SetImplementation (Ptr<SimulatorImpl> impl)
|
||||
{
|
||||
NS_FATAL_ERROR ("It is not possible to set the implementation after calling any Simulator:: function. Call Simulator::SetImplementation earlier or after Simulator::Destroy.");
|
||||
}
|
||||
*PeekImpl () = impl;
|
||||
*PeekImpl () = GetPointer (impl);
|
||||
// Set the default scheduler
|
||||
ObjectFactory factory;
|
||||
StringValue s;
|
||||
|
||||
@@ -283,6 +283,145 @@ public:
|
||||
typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
static EventId Schedule (Time const &time, void (*f) (U1,U2,U3,U4,U5), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
|
||||
|
||||
/**
|
||||
* Schedule an event with the given context.
|
||||
* A context of 0xffffffff means no context is specified.
|
||||
*
|
||||
* @param time the relative expiration time of the event.
|
||||
* @param context user-specified context parameter
|
||||
* @param mem_ptr member method pointer to invoke
|
||||
* @param obj the object on which to invoke the member method
|
||||
*/
|
||||
template <typename MEM, typename OBJ>
|
||||
static void ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj);
|
||||
|
||||
/**
|
||||
* @param time the relative expiration time of the event.
|
||||
* @param context user-specified context parameter
|
||||
* @param mem_ptr member method pointer to invoke
|
||||
* @param obj the object on which to invoke the member method
|
||||
* @param a1 the first argument to pass to the invoked method
|
||||
*/
|
||||
template <typename MEM, typename OBJ, typename T1>
|
||||
static void ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj, T1 a1);
|
||||
|
||||
/**
|
||||
* @param time the relative expiration time of the event.
|
||||
* @param context user-specified context parameter
|
||||
* @param mem_ptr member method pointer to invoke
|
||||
* @param obj the object on which to invoke the member method
|
||||
* @param a1 the first argument to pass to the invoked method
|
||||
* @param a2 the second argument to pass to the invoked method
|
||||
*/
|
||||
template <typename MEM, typename OBJ, typename T1, typename T2>
|
||||
static void ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2);
|
||||
|
||||
/**
|
||||
* @param time the relative expiration time of the event.
|
||||
* @param context user-specified context parameter
|
||||
* @param mem_ptr member method pointer to invoke
|
||||
* @param obj the object on which to invoke the member method
|
||||
* @param a1 the first argument to pass to the invoked method
|
||||
* @param a2 the second argument to pass to the invoked method
|
||||
* @param a3 the third argument to pass to the invoked method
|
||||
*/
|
||||
template <typename MEM, typename OBJ,
|
||||
typename T1, typename T2, typename T3>
|
||||
static void ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3);
|
||||
|
||||
/**
|
||||
* @param time the relative expiration time of the event.
|
||||
* @param context user-specified context parameter
|
||||
* @param mem_ptr member method pointer to invoke
|
||||
* @param obj the object on which to invoke the member method
|
||||
* @param a1 the first argument to pass to the invoked method
|
||||
* @param a2 the second argument to pass to the invoked method
|
||||
* @param a3 the third argument to pass to the invoked method
|
||||
* @param a4 the fourth argument to pass to the invoked method
|
||||
*/
|
||||
template <typename MEM, typename OBJ,
|
||||
typename T1, typename T2, typename T3, typename T4>
|
||||
static void ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4);
|
||||
|
||||
/**
|
||||
* @param time the relative expiration time of the event.
|
||||
* @param context user-specified context parameter
|
||||
* @param mem_ptr member method pointer to invoke
|
||||
* @param obj the object on which to invoke the member method
|
||||
* @param a1 the first argument to pass to the invoked method
|
||||
* @param a2 the second argument to pass to the invoked method
|
||||
* @param a3 the third argument to pass to the invoked method
|
||||
* @param a4 the fourth argument to pass to the invoked method
|
||||
* @param a5 the fifth argument to pass to the invoked method
|
||||
*/
|
||||
template <typename MEM, typename OBJ,
|
||||
typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
static void ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj,
|
||||
T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
|
||||
/**
|
||||
* @param time the relative expiration time of the event.
|
||||
* @param context user-specified context parameter
|
||||
* @param f the function to invoke
|
||||
*/
|
||||
static void ScheduleWithContext (uint32_t context, Time const &time, void (*f) (void));
|
||||
|
||||
/**
|
||||
* @param time the relative expiration time of the event.
|
||||
* @param context user-specified context parameter
|
||||
* @param f the function to invoke
|
||||
* @param a1 the first argument to pass to the function to invoke
|
||||
*/
|
||||
template <typename U1, typename T1>
|
||||
static void ScheduleWithContext (uint32_t context, Time const &time, void (*f) (U1), T1 a1);
|
||||
|
||||
/**
|
||||
* @param time the relative expiration time of the event.
|
||||
* @param context user-specified context parameter
|
||||
* @param f the function to invoke
|
||||
* @param a1 the first argument to pass to the function to invoke
|
||||
* @param a2 the second argument to pass to the function to invoke
|
||||
*/
|
||||
template <typename U1, typename U2, typename T1, typename T2>
|
||||
static void ScheduleWithContext (uint32_t context, Time const &time, void (*f) (U1,U2), T1 a1, T2 a2);
|
||||
|
||||
/**
|
||||
* @param time the relative expiration time of the event.
|
||||
* @param context user-specified context parameter
|
||||
* @param f the function to invoke
|
||||
* @param a1 the first argument to pass to the function to invoke
|
||||
* @param a2 the second argument to pass to the function to invoke
|
||||
* @param a3 the third argument to pass to the function to invoke
|
||||
*/
|
||||
template <typename U1, typename U2, typename U3, typename T1, typename T2, typename T3>
|
||||
static void ScheduleWithContext (uint32_t context, Time const &time, void (*f) (U1,U2,U3), T1 a1, T2 a2, T3 a3);
|
||||
|
||||
/**
|
||||
* @param time the relative expiration time of the event.
|
||||
* @param context user-specified context parameter
|
||||
* @param f the function to invoke
|
||||
* @param a1 the first argument to pass to the function to invoke
|
||||
* @param a2 the second argument to pass to the function to invoke
|
||||
* @param a3 the third argument to pass to the function to invoke
|
||||
* @param a4 the fourth argument to pass to the function to invoke
|
||||
*/
|
||||
template <typename U1, typename U2, typename U3, typename U4,
|
||||
typename T1, typename T2, typename T3, typename T4>
|
||||
static void ScheduleWithContext (uint32_t context, Time const &time, void (*f) (U1,U2,U3,U4), T1 a1, T2 a2, T3 a3, T4 a4);
|
||||
|
||||
/**
|
||||
* @param time the relative expiration time of the event.
|
||||
* @param context user-specified context parameter
|
||||
* @param f the function to invoke
|
||||
* @param a1 the first argument to pass to the function to invoke
|
||||
* @param a2 the second argument to pass to the function to invoke
|
||||
* @param a3 the third argument to pass to the function to invoke
|
||||
* @param a4 the fourth argument to pass to the function to invoke
|
||||
* @param a5 the fifth argument to pass to the function to invoke
|
||||
*/
|
||||
template <typename U1, typename U2, typename U3, typename U4, typename U5,
|
||||
typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
static void ScheduleWithContext (uint32_t context, Time const &time, void (*f) (U1,U2,U3,U4,U5), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5);
|
||||
|
||||
/**
|
||||
* Schedule an event to expire Now. All events scheduled to
|
||||
* to expire "Now" are scheduled FIFO, after all normal events
|
||||
@@ -588,6 +727,11 @@ public:
|
||||
*/
|
||||
static Time GetMaximumSimulationTime (void);
|
||||
|
||||
/**
|
||||
* \returns the current simulation context
|
||||
*/
|
||||
static uint32_t GetContext (void);
|
||||
|
||||
/**
|
||||
* \param time delay until the event expires
|
||||
* \param event the event to schedule
|
||||
@@ -598,6 +742,17 @@ public:
|
||||
*/
|
||||
static EventId Schedule (Time const &time, const Ptr<EventImpl> &event);
|
||||
|
||||
/**
|
||||
* \param time delay until the event expires
|
||||
* \param context event context
|
||||
* \param event the event to schedule
|
||||
* \returns a unique identifier for the newly-scheduled event.
|
||||
*
|
||||
* This method will be typically used by language bindings
|
||||
* to delegate events to their own subclass of the EventImpl base class.
|
||||
*/
|
||||
static void ScheduleWithContext (uint32_t context, Time const &time, const Ptr<EventImpl> &event);
|
||||
|
||||
/**
|
||||
* \param event the event to schedule
|
||||
* \returns a unique identifier for the newly-scheduled event.
|
||||
@@ -620,6 +775,7 @@ private:
|
||||
~Simulator ();
|
||||
|
||||
static EventId DoSchedule (Time const &time, EventImpl *event);
|
||||
static void DoScheduleWithContext (uint32_t context, Time const &time, EventImpl *event);
|
||||
static EventId DoScheduleNow (EventImpl *event);
|
||||
static EventId DoScheduleDestroy (EventImpl *event);
|
||||
};
|
||||
@@ -721,6 +877,86 @@ EventId Simulator::Schedule (Time const &time, void (*f) (U1,U2,U3,U4,U5), T1 a1
|
||||
|
||||
|
||||
|
||||
template <typename MEM, typename OBJ>
|
||||
void Simulator::ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj)
|
||||
{
|
||||
DoScheduleWithContext (context, time, MakeEvent (mem_ptr, obj));
|
||||
}
|
||||
|
||||
|
||||
template <typename MEM, typename OBJ,
|
||||
typename T1>
|
||||
void Simulator::ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj, T1 a1)
|
||||
{
|
||||
return DoScheduleWithContext (context, time, MakeEvent (mem_ptr, obj, a1));
|
||||
}
|
||||
|
||||
template <typename MEM, typename OBJ,
|
||||
typename T1, typename T2>
|
||||
void Simulator::ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2)
|
||||
{
|
||||
return DoScheduleWithContext (context, time, MakeEvent (mem_ptr, obj, a1, a2));
|
||||
}
|
||||
|
||||
template <typename MEM, typename OBJ,
|
||||
typename T1, typename T2, typename T3>
|
||||
void Simulator::ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3)
|
||||
{
|
||||
return DoScheduleWithContext (context, time, MakeEvent (mem_ptr, obj, a1, a2, a3));
|
||||
}
|
||||
|
||||
template <typename MEM, typename OBJ,
|
||||
typename T1, typename T2, typename T3, typename T4>
|
||||
void Simulator::ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj, T1 a1, T2 a2, T3 a3, T4 a4)
|
||||
{
|
||||
return DoScheduleWithContext (context, time, MakeEvent (mem_ptr, obj, a1, a2, a3, a4));
|
||||
}
|
||||
|
||||
template <typename MEM, typename OBJ,
|
||||
typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
void Simulator::ScheduleWithContext (uint32_t context, Time const &time, MEM mem_ptr, OBJ obj,
|
||||
T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
|
||||
{
|
||||
return DoScheduleWithContext (context, time, MakeEvent (mem_ptr, obj, a1, a2, a3, a4, a5));
|
||||
}
|
||||
|
||||
template <typename U1, typename T1>
|
||||
void Simulator::ScheduleWithContext (uint32_t context, Time const &time, void (*f) (U1), T1 a1)
|
||||
{
|
||||
return DoScheduleWithContext (context, time, MakeEvent (f, a1));
|
||||
}
|
||||
|
||||
template <typename U1, typename U2,
|
||||
typename T1, typename T2>
|
||||
void Simulator::ScheduleWithContext (uint32_t context, Time const &time, void (*f) (U1,U2), T1 a1, T2 a2)
|
||||
{
|
||||
return DoScheduleWithContext (context, time, MakeEvent (f, a1, a2));
|
||||
}
|
||||
|
||||
template <typename U1, typename U2, typename U3,
|
||||
typename T1, typename T2, typename T3>
|
||||
void Simulator::ScheduleWithContext (uint32_t context, Time const &time, void (*f) (U1,U2,U3), T1 a1, T2 a2, T3 a3)
|
||||
{
|
||||
return DoScheduleWithContext (context, time, MakeEvent (f, a1, a2, a3));
|
||||
}
|
||||
|
||||
template <typename U1, typename U2, typename U3, typename U4,
|
||||
typename T1, typename T2, typename T3, typename T4>
|
||||
void Simulator::ScheduleWithContext (uint32_t context, Time const &time, void (*f) (U1,U2,U3,U4), T1 a1, T2 a2, T3 a3, T4 a4)
|
||||
{
|
||||
return DoScheduleWithContext (context, time, MakeEvent (f, a1, a2, a3, a4));
|
||||
}
|
||||
|
||||
template <typename U1, typename U2, typename U3, typename U4, typename U5,
|
||||
typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
void Simulator::ScheduleWithContext (uint32_t context, Time const &time, void (*f) (U1,U2,U3,U4,U5), T1 a1, T2 a2, T3 a3, T4 a4, T5 a5)
|
||||
{
|
||||
return DoScheduleWithContext (context, time, MakeEvent (f, a1, a2, a3, a4, a5));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template <typename MEM, typename OBJ>
|
||||
EventId
|
||||
Simulator::ScheduleNow (MEM mem_ptr, OBJ obj)
|
||||
|
||||
Reference in New Issue
Block a user