Introduce Simulator::ScheduleWithContext* and Simulator::GetContext

This commit is contained in:
Guillaume Seguin
2009-11-14 17:47:05 +01:00
parent 001791bad8
commit 5ce9ad2d78
11 changed files with 398 additions and 44 deletions

View File

@@ -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
{

View File

@@ -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

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;
};

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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)