Get emu working again: Add Dix/Llc option, add and use contextual realtime schedule ops, don't refcount realtime simulator impl
This commit is contained in:
@@ -5,6 +5,8 @@ def register_types(module):
|
||||
|
||||
## emu-net-device.h: ns3::EmuNetDevice [class]
|
||||
module.add_class('EmuNetDevice', parent=root_module['ns3::NetDevice'])
|
||||
## emu-net-device.h: ns3::EmuNetDevice::EncapsulationMode [enumeration]
|
||||
module.add_enum('EncapsulationMode', ['ILLEGAL', 'DIX', 'LLC'], outer_class=root_module['ns3::EmuNetDevice'])
|
||||
|
||||
## Register a nested module for the namespace Config
|
||||
|
||||
@@ -115,6 +117,11 @@ def register_Ns3EmuNetDevice_methods(root_module, cls):
|
||||
'ns3::Ptr< ns3::Channel >',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## emu-net-device.h: ns3::EmuNetDevice::EncapsulationMode ns3::EmuNetDevice::GetEncapsulationMode() const [member function]
|
||||
cls.add_method('GetEncapsulationMode',
|
||||
'ns3::EmuNetDevice::EncapsulationMode',
|
||||
[],
|
||||
is_const=True)
|
||||
## emu-net-device.h: uint32_t ns3::EmuNetDevice::GetIfIndex() const [member function]
|
||||
cls.add_method('GetIfIndex',
|
||||
'uint32_t',
|
||||
@@ -194,6 +201,10 @@ def register_Ns3EmuNetDevice_methods(root_module, cls):
|
||||
cls.add_method('SetDataRate',
|
||||
'void',
|
||||
[param('ns3::DataRate', 'bps')])
|
||||
## emu-net-device.h: void ns3::EmuNetDevice::SetEncapsulationMode(ns3::EmuNetDevice::EncapsulationMode mode) [member function]
|
||||
cls.add_method('SetEncapsulationMode',
|
||||
'void',
|
||||
[param('ns3::EmuNetDevice::EncapsulationMode', 'mode')])
|
||||
## emu-net-device.h: void ns3::EmuNetDevice::SetIfIndex(uint32_t const index) [member function]
|
||||
cls.add_method('SetIfIndex',
|
||||
'void',
|
||||
|
||||
@@ -1486,6 +1486,14 @@ def register_Ns3RealtimeSimulatorImpl_methods(root_module, cls):
|
||||
cls.add_method('ScheduleRealtimeNow',
|
||||
'void',
|
||||
[param('ns3::EventImpl *', 'event')])
|
||||
## realtime-simulator-impl.h: void ns3::RealtimeSimulatorImpl::ScheduleRealtimeNowWithContext(uint32_t context, ns3::EventImpl * event) [member function]
|
||||
cls.add_method('ScheduleRealtimeNowWithContext',
|
||||
'void',
|
||||
[param('uint32_t', 'context'), param('ns3::EventImpl *', 'event')])
|
||||
## realtime-simulator-impl.h: void ns3::RealtimeSimulatorImpl::ScheduleRealtimeWithContext(uint32_t context, ns3::Time const & time, ns3::EventImpl * event) [member function]
|
||||
cls.add_method('ScheduleRealtimeWithContext',
|
||||
'void',
|
||||
[param('uint32_t', 'context'), param('ns3::Time const &', 'time'), param('ns3::EventImpl *', 'event')])
|
||||
## realtime-simulator-impl.h: void ns3::RealtimeSimulatorImpl::ScheduleWithContext(uint32_t context, ns3::Time const & time, ns3::EventImpl * event) [member function]
|
||||
cls.add_method('ScheduleWithContext',
|
||||
'void',
|
||||
|
||||
@@ -5,6 +5,8 @@ def register_types(module):
|
||||
|
||||
## emu-net-device.h: ns3::EmuNetDevice [class]
|
||||
module.add_class('EmuNetDevice', parent=root_module['ns3::NetDevice'])
|
||||
## emu-net-device.h: ns3::EmuNetDevice::EncapsulationMode [enumeration]
|
||||
module.add_enum('EncapsulationMode', ['ILLEGAL', 'DIX', 'LLC'], outer_class=root_module['ns3::EmuNetDevice'])
|
||||
|
||||
## Register a nested module for the namespace Config
|
||||
|
||||
@@ -115,6 +117,11 @@ def register_Ns3EmuNetDevice_methods(root_module, cls):
|
||||
'ns3::Ptr< ns3::Channel >',
|
||||
[],
|
||||
is_const=True, is_virtual=True)
|
||||
## emu-net-device.h: ns3::EmuNetDevice::EncapsulationMode ns3::EmuNetDevice::GetEncapsulationMode() const [member function]
|
||||
cls.add_method('GetEncapsulationMode',
|
||||
'ns3::EmuNetDevice::EncapsulationMode',
|
||||
[],
|
||||
is_const=True)
|
||||
## emu-net-device.h: uint32_t ns3::EmuNetDevice::GetIfIndex() const [member function]
|
||||
cls.add_method('GetIfIndex',
|
||||
'uint32_t',
|
||||
@@ -194,6 +201,10 @@ def register_Ns3EmuNetDevice_methods(root_module, cls):
|
||||
cls.add_method('SetDataRate',
|
||||
'void',
|
||||
[param('ns3::DataRate', 'bps')])
|
||||
## emu-net-device.h: void ns3::EmuNetDevice::SetEncapsulationMode(ns3::EmuNetDevice::EncapsulationMode mode) [member function]
|
||||
cls.add_method('SetEncapsulationMode',
|
||||
'void',
|
||||
[param('ns3::EmuNetDevice::EncapsulationMode', 'mode')])
|
||||
## emu-net-device.h: void ns3::EmuNetDevice::SetIfIndex(uint32_t const index) [member function]
|
||||
cls.add_method('SetIfIndex',
|
||||
'void',
|
||||
|
||||
@@ -1486,6 +1486,14 @@ def register_Ns3RealtimeSimulatorImpl_methods(root_module, cls):
|
||||
cls.add_method('ScheduleRealtimeNow',
|
||||
'void',
|
||||
[param('ns3::EventImpl *', 'event')])
|
||||
## realtime-simulator-impl.h: void ns3::RealtimeSimulatorImpl::ScheduleRealtimeNowWithContext(uint32_t context, ns3::EventImpl * event) [member function]
|
||||
cls.add_method('ScheduleRealtimeNowWithContext',
|
||||
'void',
|
||||
[param('uint32_t', 'context'), param('ns3::EventImpl *', 'event')])
|
||||
## realtime-simulator-impl.h: void ns3::RealtimeSimulatorImpl::ScheduleRealtimeWithContext(uint32_t context, ns3::Time const & time, ns3::EventImpl * event) [member function]
|
||||
cls.add_method('ScheduleRealtimeWithContext',
|
||||
'void',
|
||||
[param('uint32_t', 'context'), param('ns3::Time const &', 'time'), param('ns3::EventImpl *', 'event')])
|
||||
## realtime-simulator-impl.h: void ns3::RealtimeSimulatorImpl::ScheduleWithContext(uint32_t context, ns3::Time const & time, ns3::EventImpl * event) [member function]
|
||||
cls.add_method('ScheduleWithContext',
|
||||
'void',
|
||||
|
||||
@@ -75,6 +75,7 @@ int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
std::string deviceName ("eth1");
|
||||
std::string encapMode ("Dix");
|
||||
uint32_t nNodes = 4;
|
||||
|
||||
//
|
||||
@@ -83,7 +84,9 @@ main (int argc, char *argv[])
|
||||
//
|
||||
CommandLine cmd;
|
||||
cmd.AddValue("deviceName", "device name", deviceName);
|
||||
cmd.AddValue("encapsulationMode", "encapsulation mode of emu device (\"Dix\" [default] or \"Llc\")", encapMode);
|
||||
cmd.AddValue("nNodes", "number of nodes to create (>= 2)", nNodes);
|
||||
|
||||
cmd.Parse (argc, argv);
|
||||
|
||||
GlobalValue::Bind ("SimulatorImplementationType",
|
||||
@@ -110,6 +113,8 @@ main (int argc, char *argv[])
|
||||
NS_LOG_INFO ("Create channels.");
|
||||
EmuHelper emu;
|
||||
emu.SetAttribute ("DeviceName", StringValue (deviceName));
|
||||
emu.SetAttribute ("EncapsulationMode", StringValue (encapMode));
|
||||
|
||||
NetDeviceContainer d = emu.Install (n);
|
||||
|
||||
//
|
||||
@@ -133,8 +138,8 @@ main (int argc, char *argv[])
|
||||
// Create a UdpEchoClient application to send UDP datagrams from node zero to node one.
|
||||
//
|
||||
uint32_t packetSize = 1024;
|
||||
uint32_t maxPacketCount = 1;
|
||||
Time interPacketInterval = Seconds (1.);
|
||||
uint32_t maxPacketCount = 20;
|
||||
Time interPacketInterval = Seconds (0.1);
|
||||
UdpEchoClientHelper client (i.GetAddress (1), 9);
|
||||
client.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
|
||||
client.SetAttribute ("Interval", TimeValue (interPacketInterval));
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
#include "ns3/trace-source-accessor.h"
|
||||
#include "ns3/channel.h"
|
||||
#include "ns3/system-thread.h"
|
||||
#include "ns3/realtime-simulator-impl.h"
|
||||
#include "ns3/mac48-address.h"
|
||||
#include "ns3/enum.h"
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -83,6 +83,12 @@ EmuNetDevice::GetTypeId (void)
|
||||
TimeValue (Seconds (0.)),
|
||||
MakeTimeAccessor (&EmuNetDevice::m_tStop),
|
||||
MakeTimeChecker ())
|
||||
.AddAttribute ("EncapsulationMode",
|
||||
"The link-layer encapsulation type to use.",
|
||||
EnumValue (LLC),
|
||||
MakeEnumAccessor (&EmuNetDevice::SetEncapsulationMode),
|
||||
MakeEnumChecker (DIX, "Dix",
|
||||
LLC, "Llc"))
|
||||
|
||||
//
|
||||
// Transmit queueing discipline for the device which includes its own set
|
||||
@@ -165,7 +171,6 @@ EmuNetDevice::GetTypeId (void)
|
||||
return tid;
|
||||
}
|
||||
|
||||
|
||||
EmuNetDevice::EmuNetDevice ()
|
||||
:
|
||||
m_startEvent (),
|
||||
@@ -178,11 +183,17 @@ EmuNetDevice::EmuNetDevice ()
|
||||
m_isMulticast (false)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_packetBuffer = new uint8_t[65536];
|
||||
Start (m_tStart);
|
||||
}
|
||||
|
||||
EmuNetDevice::~EmuNetDevice ()
|
||||
{
|
||||
if (m_packetBuffer)
|
||||
{
|
||||
delete [] m_packetBuffer;
|
||||
m_packetBuffer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -193,6 +204,21 @@ EmuNetDevice::DoDispose()
|
||||
NetDevice::DoDispose ();
|
||||
}
|
||||
|
||||
void
|
||||
EmuNetDevice::SetEncapsulationMode (enum EncapsulationMode mode)
|
||||
{
|
||||
NS_LOG_FUNCTION (mode);
|
||||
m_encapMode = mode;
|
||||
NS_LOG_LOGIC ("m_encapMode = " << m_encapMode);
|
||||
}
|
||||
|
||||
EmuNetDevice::EncapsulationMode
|
||||
EmuNetDevice::GetEncapsulationMode (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
return m_encapMode;
|
||||
}
|
||||
|
||||
void
|
||||
EmuNetDevice::Start (Time tStart)
|
||||
{
|
||||
@@ -203,6 +229,20 @@ EmuNetDevice::Start (Time tStart)
|
||||
//
|
||||
Simulator::Cancel (m_startEvent);
|
||||
m_startEvent = Simulator::Schedule (tStart, &EmuNetDevice::StartDevice, this);
|
||||
|
||||
//
|
||||
// We're going to need a pointer to the realtime simulator implementation.
|
||||
// It's important to remember that access to that implementation may happen
|
||||
// in a completely different thread than the simulator is running in. We are
|
||||
// talking about multiple threads here, so it is very, very dangerous to do
|
||||
// any kind of reference couning on a shared object. So what we are going to
|
||||
// do is to get a reference to the realtime simulator and then save a raw
|
||||
// pointer to that implementation for use by the other threads. We must not
|
||||
// free this pointer or we may delete the simulator out from under us an
|
||||
// everyone else.
|
||||
//
|
||||
Ptr<RealtimeSimulatorImpl> impl = DynamicCast<RealtimeSimulatorImpl> (Simulator::GetImplementation ());
|
||||
m_rtImpl = GetPointer (impl);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -308,6 +348,7 @@ EmuNetDevice::StartDevice (void)
|
||||
// This one is OK to enable at runtime
|
||||
m_isMulticast = true;
|
||||
}
|
||||
|
||||
//
|
||||
// Now spin up a read thread to read packets.
|
||||
//
|
||||
@@ -563,6 +604,10 @@ EmuNetDevice::FindCreator (std::string creatorName)
|
||||
locations.push_back ("../../../build/optimized/src/devices/emu/");
|
||||
locations.push_back ("../../../build/debug/src/devices/emu/");
|
||||
|
||||
// src/devices/emu (or build/debug/examples/emulation)
|
||||
locations.push_back ("../../../../build/optimized/src/devices/emu/");
|
||||
locations.push_back ("../../../../build/debug/src/devices/emu/");
|
||||
|
||||
for (std::list<std::string>::const_iterator i = locations.begin (); i != locations.end (); ++i)
|
||||
{
|
||||
struct stat st;
|
||||
@@ -632,31 +677,43 @@ EmuNetDevice::ForwardUp (uint8_t *buf, uint32_t len)
|
||||
|
||||
uint16_t protocol;
|
||||
|
||||
//
|
||||
// If the length/type is less than 1500, it corresponds to a length
|
||||
// interpretation packet. In this case, it is an 802.3 packet and
|
||||
// will also have an 802.2 LLC header. If greater than 1500, we
|
||||
// find the protocol number (Ethernet type) directly.
|
||||
//
|
||||
if (header.GetLengthType () <= 1500)
|
||||
switch (m_encapMode)
|
||||
{
|
||||
LlcSnapHeader llc;
|
||||
case LLC:
|
||||
//
|
||||
// Check to see that the packet is long enough to possibly contain the
|
||||
// header we want to remove before just naively calling.
|
||||
// If the length/type is less than 1500, it corresponds to a length
|
||||
// interpretation packet. In this case, it is an 802.3 packet and
|
||||
// will also have an 802.2 LLC header. If greater than 1500, we
|
||||
// find the protocol number (Ethernet type) directly.
|
||||
//
|
||||
if (packet->GetSize() < llc.GetSerializedSize())
|
||||
if (header.GetLengthType () <= 1500)
|
||||
{
|
||||
m_phyRxDropTrace (originalPacket);
|
||||
return;
|
||||
}
|
||||
LlcSnapHeader llc;
|
||||
//
|
||||
// Check to see that the packet is long enough to possibly contain the
|
||||
// header we want to remove before just naively calling.
|
||||
//
|
||||
if (packet->GetSize() < llc.GetSerializedSize())
|
||||
{
|
||||
m_phyRxDropTrace (originalPacket);
|
||||
return;
|
||||
}
|
||||
|
||||
packet->RemoveHeader (llc);
|
||||
protocol = llc.GetType ();
|
||||
}
|
||||
else
|
||||
{
|
||||
packet->RemoveHeader (llc);
|
||||
protocol = llc.GetType ();
|
||||
}
|
||||
else
|
||||
{
|
||||
protocol = header.GetLengthType ();
|
||||
}
|
||||
break;
|
||||
|
||||
case DIX:
|
||||
protocol = header.GetLengthType ();
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_FATAL_ERROR ("invalid encapsulation mode");
|
||||
}
|
||||
|
||||
PacketType packetType;
|
||||
@@ -709,13 +766,9 @@ EmuNetDevice::ReadThread (void)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
|
||||
//
|
||||
// It's important to remember that we're in a completely different thread than the simulator is running in. We
|
||||
// need to synchronize with that other thread to get the packet up into ns-3. What we will need to do is to schedule
|
||||
// a method to forward up the packet using the multithreaded simulator we are most certainly running. However, I just
|
||||
// said it -- we are talking about two threads here, so it is very, very dangerous to do any kind of reference couning
|
||||
// on a shared object. Just don't do it. So what we're going to do is to allocate a buffer on the heap and pass that
|
||||
// buffer into the ns-3 context thread where it will create the packet.
|
||||
// It's important to remember that we're in a completely different thread than the simulator is running in.
|
||||
// We are talking about multiple threads here, so it is very, very dangerous to do any kind of reference couning
|
||||
// on a shared object.
|
||||
//
|
||||
|
||||
int32_t len = -1;
|
||||
@@ -724,6 +777,10 @@ EmuNetDevice::ReadThread (void)
|
||||
|
||||
for (;;)
|
||||
{
|
||||
//
|
||||
// to avoid any issues with a shared reference counted packet, we allocate a buffer on the heap and pass that
|
||||
// buffer into the ns-3 context thread where it will create the packet, copy the buffer and then free it.
|
||||
//
|
||||
uint32_t bufferSize = 65536;
|
||||
uint8_t *buf = (uint8_t *)malloc (bufferSize);
|
||||
if (buf == 0)
|
||||
@@ -743,8 +800,8 @@ EmuNetDevice::ReadThread (void)
|
||||
|
||||
NS_LOG_INFO ("EmuNetDevice::ReadThread(): Received packet");
|
||||
NS_LOG_INFO ("EmuNetDevice::ReadThread(): Scheduling handler");
|
||||
DynamicCast<RealtimeSimulatorImpl> (Simulator::GetImplementation ())->ScheduleRealtimeNow (
|
||||
MakeEvent (&EmuNetDevice::ForwardUp, this, buf, len));
|
||||
NS_ASSERT_MSG (m_rtImpl, "EmuNetDevice::ReadThread(): Realtime simulator implementation pointer not set");
|
||||
m_rtImpl->ScheduleRealtimeNowWithContext (GetNode ()->GetId (), MakeEvent (&EmuNetDevice::ForwardUp, this, buf, len));
|
||||
buf = 0;
|
||||
}
|
||||
}
|
||||
@@ -795,19 +852,30 @@ EmuNetDevice::SendFrom (Ptr<Packet> packet, const Address &src, const Address &d
|
||||
NS_LOG_LOGIC ("Transmit packet from " << source);
|
||||
NS_LOG_LOGIC ("Transmit packet to " << destination);
|
||||
|
||||
//
|
||||
// We've got to pick either DIX (Ethernet) or LLC/SNAP (IEEE 802.3) as a
|
||||
// packet format. IEEE 802.3 is slightly more formally correct, so we
|
||||
// go that route.
|
||||
//
|
||||
LlcSnapHeader llc;
|
||||
llc.SetType (protocolNumber);
|
||||
packet->AddHeader (llc);
|
||||
|
||||
EthernetHeader header (false);
|
||||
header.SetSource (source);
|
||||
header.SetDestination (destination);
|
||||
header.SetLengthType (packet->GetSize ());
|
||||
|
||||
switch (m_encapMode)
|
||||
{
|
||||
case LLC:
|
||||
{
|
||||
LlcSnapHeader llc;
|
||||
llc.SetType (protocolNumber);
|
||||
packet->AddHeader (llc);
|
||||
|
||||
header.SetLengthType (packet->GetSize ());
|
||||
}
|
||||
break;
|
||||
|
||||
case DIX:
|
||||
header.SetLengthType (protocolNumber);
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_FATAL_ERROR ("invalid encapsulation mode");
|
||||
}
|
||||
|
||||
packet->AddHeader (header);
|
||||
|
||||
//
|
||||
@@ -827,7 +895,6 @@ EmuNetDevice::SendFrom (Ptr<Packet> packet, const Address &src, const Address &d
|
||||
m_promiscSnifferTrace (packet);
|
||||
m_snifferTrace (packet);
|
||||
|
||||
|
||||
struct sockaddr_ll ll;
|
||||
bzero (&ll, sizeof (ll));
|
||||
|
||||
@@ -837,8 +904,10 @@ EmuNetDevice::SendFrom (Ptr<Packet> packet, const Address &src, const Address &d
|
||||
|
||||
NS_LOG_LOGIC ("calling sendto");
|
||||
|
||||
int32_t rc;
|
||||
rc = sendto (m_sock, packet->PeekData (), packet->GetSize (), 0, reinterpret_cast<struct sockaddr *> (&ll), sizeof (ll));
|
||||
NS_ASSERT_MSG (packet->GetSize () <= 65536, "EmuNetDevice::SendFrom(): Packet too big " << packet->GetSize ());
|
||||
packet->CopyData (m_packetBuffer, packet->GetSize ());
|
||||
|
||||
int32_t rc = sendto (m_sock, m_packetBuffer, packet->GetSize (), 0, reinterpret_cast<struct sockaddr *> (&ll), sizeof (ll));
|
||||
NS_LOG_LOGIC ("sendto returns " << rc);
|
||||
|
||||
return rc == -1 ? false : true;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "ns3/ptr.h"
|
||||
#include "ns3/mac48-address.h"
|
||||
#include "ns3/system-thread.h"
|
||||
#include "ns3/realtime-simulator-impl.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -46,6 +47,15 @@ class EmuNetDevice : public NetDevice
|
||||
public:
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
/**
|
||||
* Enumeration of the types of packets supported in the class.
|
||||
*/
|
||||
enum EncapsulationMode {
|
||||
ILLEGAL, /**< Encapsulation mode not set */
|
||||
DIX, /**< DIX II / Ethernet II packet */
|
||||
LLC, /**< 802.2 LLC/SNAP Packet*/
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct a EmuNetDevice
|
||||
*
|
||||
@@ -176,6 +186,22 @@ public:
|
||||
|
||||
virtual bool SupportsSendFrom (void) const;
|
||||
|
||||
/**
|
||||
* Set the encapsulation mode of this device.
|
||||
*
|
||||
* \param mode The encapsulation mode of this device.
|
||||
*
|
||||
* \see SetFrameSize
|
||||
*/
|
||||
void SetEncapsulationMode (EmuNetDevice::EncapsulationMode mode);
|
||||
|
||||
/**
|
||||
* Get the encapsulation mode of this device.
|
||||
*
|
||||
* \returns The encapsulation mode of this device.
|
||||
*/
|
||||
EmuNetDevice::EncapsulationMode GetEncapsulationMode (void) const;
|
||||
|
||||
private:
|
||||
|
||||
virtual void DoDispose (void);
|
||||
@@ -444,6 +470,13 @@ private:
|
||||
*/
|
||||
int32_t m_sll_ifindex;
|
||||
|
||||
/**
|
||||
* The type of packet that should be created by the AddHeader
|
||||
* function and that should be processed by the ProcessHeader
|
||||
* function.
|
||||
*/
|
||||
EncapsulationMode m_encapMode;
|
||||
|
||||
/**
|
||||
* Flag indicating whether or not the link is up. In this case,
|
||||
* whether or not the device is connected to a channel.
|
||||
@@ -471,6 +504,17 @@ private:
|
||||
* The unix/linux name of the underlying device (e.g., eth0)
|
||||
*/
|
||||
std::string m_deviceName;
|
||||
|
||||
/**
|
||||
* A 64K buffer to hold packet data while it is being sent.
|
||||
*/
|
||||
uint8_t *m_packetBuffer;
|
||||
|
||||
/**
|
||||
* A copy of a raw pointer to the required real-time simulator implementation.
|
||||
* Never free this pointer!
|
||||
*/
|
||||
RealtimeSimulatorImpl *m_rtImpl;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -620,10 +620,9 @@ RealtimeSimulatorImpl::Now (void) const
|
||||
// Schedule an event for a _relative_ time in the future.
|
||||
//
|
||||
void
|
||||
RealtimeSimulatorImpl::ScheduleRealtime (Time const &time, EventImpl *impl)
|
||||
RealtimeSimulatorImpl::ScheduleRealtimeWithContext (uint32_t context, Time const &time, EventImpl *impl)
|
||||
{
|
||||
NS_LOG_FUNCTION (time << impl);
|
||||
|
||||
NS_LOG_FUNCTION (context << time << impl);
|
||||
|
||||
{
|
||||
CriticalSection cs (m_mutex);
|
||||
@@ -639,13 +638,19 @@ RealtimeSimulatorImpl::ScheduleRealtime (Time const &time, EventImpl *impl)
|
||||
m_events->Insert (ev);
|
||||
m_synchronizer->Signal ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
RealtimeSimulatorImpl::ScheduleRealtimeNow (EventImpl *impl)
|
||||
RealtimeSimulatorImpl::ScheduleRealtime (Time const &time, EventImpl *impl)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
NS_LOG_FUNCTION (time << impl);
|
||||
ScheduleRealtimeWithContext (GetContext (), time, impl);
|
||||
}
|
||||
|
||||
void
|
||||
RealtimeSimulatorImpl::ScheduleRealtimeNowWithContext (uint32_t context, EventImpl *impl)
|
||||
{
|
||||
NS_LOG_FUNCTION (context << impl);
|
||||
{
|
||||
CriticalSection cs (m_mutex);
|
||||
|
||||
@@ -654,11 +659,13 @@ RealtimeSimulatorImpl::ScheduleRealtimeNow (EventImpl *impl)
|
||||
// realtime clock. If we're not, then m_currentTs is were we stopped.
|
||||
//
|
||||
uint64_t ts = m_running ? m_synchronizer->GetCurrentRealtime () : m_currentTs;
|
||||
NS_ASSERT_MSG (ts >= m_currentTs, "RealtimeSimulatorImpl::ScheduleRealtimeNow(): schedule for time < m_currentTs");
|
||||
NS_ASSERT_MSG (ts >= m_currentTs,
|
||||
"RealtimeSimulatorImpl::ScheduleRealtimeNowWithContext(): schedule for time < m_currentTs");
|
||||
Scheduler::Event ev;
|
||||
ev.impl = impl;
|
||||
ev.key.m_ts = ts;
|
||||
ev.key.m_uid = m_uid;
|
||||
ev.key.m_context = context;
|
||||
m_uid++;
|
||||
m_unscheduledEvents++;
|
||||
m_events->Insert (ev);
|
||||
@@ -666,6 +673,13 @@ RealtimeSimulatorImpl::ScheduleRealtimeNow (EventImpl *impl)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RealtimeSimulatorImpl::ScheduleRealtimeNow (EventImpl *impl)
|
||||
{
|
||||
NS_LOG_FUNCTION (impl);
|
||||
ScheduleRealtimeNowWithContext (GetContext (), impl);
|
||||
}
|
||||
|
||||
Time
|
||||
RealtimeSimulatorImpl::RealtimeNow (void) const
|
||||
{
|
||||
|
||||
@@ -71,7 +71,9 @@ public:
|
||||
virtual void SetScheduler (ObjectFactory schedulerFactory);
|
||||
virtual uint32_t GetContext (void) const;
|
||||
|
||||
void ScheduleRealtimeWithContext (uint32_t context, Time const &time, EventImpl *event);
|
||||
void ScheduleRealtime (Time const &time, EventImpl *event);
|
||||
void ScheduleRealtimeNowWithContext (uint32_t context, EventImpl *event);
|
||||
void ScheduleRealtimeNow (EventImpl *event);
|
||||
Time RealtimeNow (void) const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user