From 6fef34be47874ef96a7dd7cdc3632cf682fa85b0 Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Wed, 8 Mar 2017 18:01:29 +0100 Subject: [PATCH] network: Convert Queue into a template class --- examples/tcp/tcp-variants-comparison.cc | 2 +- .../traffic-control/queue-discs-benchmark.cc | 14 +- examples/traffic-control/traffic-control.cc | 2 +- src/core/model/object-base.h | 41 ++ src/csma/helper/csma-helper.cc | 14 +- src/csma/model/csma-net-device.cc | 26 +- src/csma/model/csma-net-device.h | 8 +- src/flow-monitor/model/ipv4-flow-probe.cc | 2 +- src/flow-monitor/model/ipv4-flow-probe.h | 5 +- src/flow-monitor/model/ipv6-flow-probe.cc | 2 +- src/flow-monitor/model/ipv6-flow-probe.h | 5 +- src/internet/model/ipv4-interface.cc | 1 + src/internet/model/ipv4-interface.h | 2 +- src/internet/model/ipv4-packet-filter.cc | 1 + src/internet/model/ipv4-queue-disc-item.cc | 7 +- src/internet/model/ipv4-queue-disc-item.h | 7 +- src/internet/model/ipv6-interface.cc | 1 + src/internet/model/ipv6-interface.h | 2 +- src/internet/model/ipv6-packet-filter.cc | 1 + src/internet/model/ipv6-queue-disc-item.cc | 7 +- src/internet/model/ipv6-queue-disc-item.h | 7 +- src/internet/test/tcp-general-test.cc | 1 + src/internet/test/tcp-slow-start-test.cc | 1 + src/internet/test/udp-test.cc | 4 +- src/lte/test/lte-simple-net-device.cc | 1 + .../helper/simple-net-device-helper.cc | 7 +- src/network/model/net-device.cc | 240 --------- src/network/model/net-device.h | 307 +----------- .../test/drop-tail-queue-test-suite.cc | 34 +- src/network/utils/drop-tail-queue.cc | 76 +-- src/network/utils/drop-tail-queue.h | 98 +++- .../utils/net-device-queue-interface.cc | 246 +++++++++ .../utils/net-device-queue-interface.h | 257 ++++++++++ src/network/utils/queue-item.cc | 128 +++++ src/network/utils/queue-item.h | 233 +++++++++ src/network/utils/queue.cc | 281 ++++------- src/network/utils/queue.h | 473 +++++++++++++++--- src/network/utils/simple-net-device.cc | 18 +- src/network/utils/simple-net-device.h | 8 +- src/network/wscript | 4 + .../examples/main-attribute-value.cc | 12 +- .../helper/point-to-point-helper.cc | 16 +- .../helper/point-to-point-helper.h | 1 - .../model/point-to-point-net-device.cc | 26 +- .../model/point-to-point-net-device.h | 9 +- .../test/point-to-point-test.cc | 5 +- .../adhoc-aloha-noack-ideal-phy-helper.cc | 4 +- src/spectrum/model/aloha-noack-net-device.cc | 14 +- src/spectrum/model/aloha-noack-net-device.h | 6 +- .../model/non-communicating-net-device.cc | 1 - .../model/non-communicating-net-device.h | 1 - .../ns3tc/pfifo-fast-queue-disc-test-suite.cc | 12 +- src/test/ns3tcp/ns3tcp-state-test-suite.cc | 2 +- .../examples/adaptive-red-tests.cc | 2 +- .../examples/codel-vs-pfifo-asymmetric.cc | 4 +- .../examples/codel-vs-pfifo-basic-test.cc | 4 +- src/traffic-control/examples/pfifo-vs-red.cc | 8 +- src/traffic-control/examples/red-tests.cc | 6 +- src/traffic-control/examples/red-vs-ared.cc | 8 +- .../helper/traffic-control-helper.cc | 9 +- .../helper/traffic-control-helper.h | 2 - src/traffic-control/model/codel-queue-disc.cc | 38 +- src/traffic-control/model/codel-queue-disc.h | 25 +- .../model/fq-codel-queue-disc.cc | 11 +- .../model/pfifo-fast-queue-disc.cc | 24 +- src/traffic-control/model/pie-queue-disc.cc | 44 +- src/traffic-control/model/pie-queue-disc.h | 26 +- src/traffic-control/model/queue-disc.cc | 90 +--- src/traffic-control/model/queue-disc.h | 121 +---- src/traffic-control/model/red-queue-disc.cc | 46 +- src/traffic-control/model/red-queue-disc.h | 27 +- .../model/traffic-control-layer.cc | 15 +- .../model/traffic-control-layer.h | 5 +- .../adaptive-red-queue-disc-test-suite.cc | 8 +- .../test/codel-queue-disc-test-suite.cc | 37 +- .../test/pie-queue-disc-test-suite.cc | 7 +- .../test/red-queue-disc-test-suite.cc | 8 +- .../model/virtual-net-device.cc | 1 - src/wifi/model/wifi-net-device.cc | 1 + src/wifi/model/wifi-net-device.h | 2 + 80 files changed, 1888 insertions(+), 1374 deletions(-) create mode 100644 src/network/utils/net-device-queue-interface.cc create mode 100644 src/network/utils/net-device-queue-interface.h create mode 100644 src/network/utils/queue-item.cc create mode 100644 src/network/utils/queue-item.h diff --git a/examples/tcp/tcp-variants-comparison.cc b/examples/tcp/tcp-variants-comparison.cc index 12f1a490b..a3ef07f15 100644 --- a/examples/tcp/tcp-variants-comparison.cc +++ b/examples/tcp/tcp-variants-comparison.cc @@ -383,7 +383,7 @@ int main (int argc, char *argv[]) Time access_d (access_delay); Time bottle_d (delay); - Config::SetDefault ("ns3::CoDelQueueDisc::Mode", EnumValue (Queue::QUEUE_MODE_BYTES)); + Config::SetDefault ("ns3::CoDelQueueDisc::Mode", EnumValue (CoDelQueueDisc::QUEUE_DISC_MODE_BYTES)); uint32_t size = (std::min (access_b, bottle_b).GetBitRate () / 8) * ((access_d + bottle_d) * 2).GetSeconds (); diff --git a/examples/traffic-control/queue-discs-benchmark.cc b/examples/traffic-control/queue-discs-benchmark.cc index 0b99c68f7..da4d2602a 100644 --- a/examples/traffic-control/queue-discs-benchmark.cc +++ b/examples/traffic-control/queue-discs-benchmark.cc @@ -158,13 +158,13 @@ int main (int argc, char *argv[]) { tchBottleneck.SetRootQueueDisc ("ns3::RedQueueDisc"); Config::SetDefault ("ns3::RedQueueDisc::ARED", BooleanValue (true)); - Config::SetDefault ("ns3::RedQueueDisc::Mode", EnumValue (Queue::QUEUE_MODE_PACKETS)); + Config::SetDefault ("ns3::RedQueueDisc::Mode", EnumValue (RedQueueDisc::QUEUE_DISC_MODE_PACKETS)); Config::SetDefault ("ns3::RedQueueDisc::QueueLimit", UintegerValue (queueDiscSize)); } else if (queueDiscType.compare ("CoDel") == 0) { tchBottleneck.SetRootQueueDisc ("ns3::CoDelQueueDisc"); - Config::SetDefault ("ns3::CoDelQueueDisc::Mode", EnumValue (Queue::QUEUE_MODE_PACKETS)); + Config::SetDefault ("ns3::CoDelQueueDisc::Mode", EnumValue (CoDelQueueDisc::QUEUE_DISC_MODE_PACKETS)); Config::SetDefault ("ns3::CoDelQueueDisc::MaxPackets", UintegerValue (queueDiscSize)); } else if (queueDiscType.compare ("FqCoDel") == 0) @@ -177,7 +177,7 @@ int main (int argc, char *argv[]) else if (queueDiscType.compare ("PIE") == 0) { tchBottleneck.SetRootQueueDisc ("ns3::PieQueueDisc"); - Config::SetDefault ("ns3::PieQueueDisc::Mode", EnumValue (Queue::QUEUE_MODE_PACKETS)); + Config::SetDefault ("ns3::PieQueueDisc::Mode", EnumValue (PieQueueDisc::QUEUE_DISC_MODE_PACKETS)); Config::SetDefault ("ns3::PieQueueDisc::QueueLimit", UintegerValue (queueDiscSize)); } else @@ -190,8 +190,8 @@ int main (int argc, char *argv[]) tchBottleneck.SetQueueLimits ("ns3::DynamicQueueLimits"); } - Config::SetDefault ("ns3::Queue::Mode", StringValue ("QUEUE_MODE_PACKETS")); - Config::SetDefault ("ns3::Queue::MaxPackets", UintegerValue (100)); + Config::SetDefault ("ns3::QueueBase::Mode", StringValue ("QUEUE_MODE_PACKETS")); + Config::SetDefault ("ns3::QueueBase::MaxPackets", UintegerValue (100)); NetDeviceContainer devicesAccessLink = accessLink.Install (n1.Get (0), n2.Get (0)); tchPfifoFastAccess.Install (devicesAccessLink); @@ -200,7 +200,7 @@ int main (int argc, char *argv[]) address.NewNetwork (); Ipv4InterfaceContainer interfacesAccess = address.Assign (devicesAccessLink); - Config::SetDefault ("ns3::Queue::MaxPackets", UintegerValue (netdevicesQueueSize)); + Config::SetDefault ("ns3::QueueBase::MaxPackets", UintegerValue (netdevicesQueueSize)); NetDeviceContainer devicesBottleneckLink = bottleneckLink.Install (n2.Get (0), n3.Get (0)); QueueDiscContainer qdiscs; @@ -220,7 +220,7 @@ int main (int argc, char *argv[]) Ptr streamLimits = ascii.CreateFileStream (queueDiscType + "-limits.txt"); queueLimits->TraceConnectWithoutContext ("Limit",MakeBoundCallback (&LimitsTrace, streamLimits)); } - Ptr queue = StaticCast (devicesBottleneckLink.Get (0))->GetQueue (); + Ptr > queue = StaticCast (devicesBottleneckLink.Get (0))->GetQueue (); Ptr streamBytesInQueue = ascii.CreateFileStream (queueDiscType + "-bytesInQueue.txt"); queue->TraceConnectWithoutContext ("BytesInQueue",MakeBoundCallback (&BytesInQueueTrace, streamBytesInQueue)); diff --git a/examples/traffic-control/traffic-control.cc b/examples/traffic-control/traffic-control.cc index e91876616..0bdbc3bd1 100644 --- a/examples/traffic-control/traffic-control.cc +++ b/examples/traffic-control/traffic-control.cc @@ -126,7 +126,7 @@ main (int argc, char *argv[]) Ptr nd = devices.Get (1); Ptr ptpnd = DynamicCast (nd); - Ptr queue = ptpnd->GetQueue (); + Ptr > queue = ptpnd->GetQueue (); queue->TraceConnectWithoutContext ("PacketsInQueue", MakeCallback (&DevicePacketsInQueueTrace)); Ipv4AddressHelper address; diff --git a/src/core/model/object-base.h b/src/core/model/object-base.h index 3d3566d1c..9c3881325 100644 --- a/src/core/model/object-base.h +++ b/src/core/model/object-base.h @@ -51,8 +51,49 @@ } \ } Object ## type ## RegistrationVariable + +/** + * \ingroup object + * \brief Explicitly instantiate a template class and register the resulting + * instance with the TypeId system. + * + * This macro should be invoked once for every required instance of a template + * class which derives from the Object class and defines a new GetTypeId method. + * + * If the template class is in a namespace, then the macro call should also be + * in the namespace. + */ +#define NS_OBJECT_TEMPLATE_CLASS_DEFINE(type,param) \ + template class type; \ + template <> std::string DoGetTypeParamName > () \ + { \ + return #param; \ + } \ + static struct Object ## type ## param ## RegistrationClass \ + { \ + Object ## type ## param ## RegistrationClass () { \ + ns3::TypeId tid = type::GetTypeId (); \ + tid.SetSize (sizeof (type)); \ + tid.GetParent (); \ + } \ + } Object ## type ## param ## RegistrationVariable + + namespace ns3 { +// Helper function to get the name (as a string) of the type parameter +// of a template class +template +std::string DoGetTypeParamName (void); + +// Helper function to get the name (as a string) of the type parameter +// of a template class +template +std::string GetTypeParamName (void) +{ + return DoGetTypeParamName (); +} + class AttributeConstructionList; /** diff --git a/src/csma/helper/csma-helper.cc b/src/csma/helper/csma-helper.cc index e4f5a4b50..cb73da64e 100644 --- a/src/csma/helper/csma-helper.cc +++ b/src/csma/helper/csma-helper.cc @@ -40,7 +40,7 @@ NS_LOG_COMPONENT_DEFINE ("CsmaHelper"); CsmaHelper::CsmaHelper () { - m_queueFactory.SetTypeId ("ns3::DropTailQueue"); + m_queueFactory.SetTypeId ("ns3::DropTailQueue"); m_deviceFactory.SetTypeId ("ns3::CsmaNetDevice"); m_channelFactory.SetTypeId ("ns3::CsmaChannel"); } @@ -52,6 +52,8 @@ CsmaHelper::SetQueue (std::string type, std::string n3, const AttributeValue &v3, std::string n4, const AttributeValue &v4) { + QueueBase::AppendItemTypeIfNotPresent (type, "Packet"); + m_queueFactory.SetTypeId (type); m_queueFactory.Set (n1, v1); m_queueFactory.Set (n2, v2); @@ -171,10 +173,10 @@ CsmaHelper::EnableAsciiInternal ( // The "+", '-', and 'd' events are driven by trace sources actually in the // transmit queue. // - Ptr queue = device->GetQueue (); - asciiTraceHelper.HookDefaultEnqueueSinkWithoutContext (queue, "Enqueue", theStream); - asciiTraceHelper.HookDefaultDropSinkWithoutContext (queue, "Drop", theStream); - asciiTraceHelper.HookDefaultDequeueSinkWithoutContext (queue, "Dequeue", theStream); + Ptr > queue = device->GetQueue (); + asciiTraceHelper.HookDefaultEnqueueSinkWithoutContext > (queue, "Enqueue", theStream); + asciiTraceHelper.HookDefaultDropSinkWithoutContext > (queue, "Drop", theStream); + asciiTraceHelper.HookDefaultDequeueSinkWithoutContext > (queue, "Dequeue", theStream); return; } @@ -304,7 +306,7 @@ CsmaHelper::InstallPriv (Ptr node, Ptr channel) const Ptr device = m_deviceFactory.Create (); device->SetAddress (Mac48Address::Allocate ()); node->AddDevice (device); - Ptr queue = m_queueFactory.Create (); + Ptr > queue = m_queueFactory.Create > (); device->SetQueue (queue); device->Attach (channel); diff --git a/src/csma/model/csma-net-device.cc b/src/csma/model/csma-net-device.cc index 37d15455d..3dbbe08e2 100644 --- a/src/csma/model/csma-net-device.cc +++ b/src/csma/model/csma-net-device.cc @@ -86,7 +86,7 @@ CsmaNetDevice::GetTypeId (void) "A queue to use as the transmit queue in the device.", PointerValue (), MakePointerAccessor (&CsmaNetDevice::m_queue), - MakePointerChecker ()) + MakePointerChecker > ()) // // Trace sources at the "top" of the net device, where packets transition @@ -564,9 +564,9 @@ CsmaNetDevice::TransmitAbort (void) } else { - Ptr item = m_queue->Dequeue (); - NS_ASSERT_MSG (item != 0, "CsmaNetDevice::TransmitAbort(): IsEmpty false but no Packet on queue?"); - m_currentPkt = item->GetPacket (); + Ptr packet = m_queue->Dequeue (); + NS_ASSERT_MSG (packet != 0, "CsmaNetDevice::TransmitAbort(): IsEmpty false but no Packet on queue?"); + m_currentPkt = packet; m_snifferTrace (m_currentPkt); m_promiscSnifferTrace (m_currentPkt); TransmitStart (); @@ -633,9 +633,9 @@ CsmaNetDevice::TransmitReadyEvent (void) } else { - Ptr item = m_queue->Dequeue (); - NS_ASSERT_MSG (item != 0, "CsmaNetDevice::TransmitReadyEvent(): IsEmpty false but no Packet on queue?"); - m_currentPkt = item->GetPacket (); + Ptr packet = m_queue->Dequeue (); + NS_ASSERT_MSG (packet != 0, "CsmaNetDevice::TransmitReadyEvent(): IsEmpty false but no Packet on queue?"); + m_currentPkt = packet; m_snifferTrace (m_currentPkt); m_promiscSnifferTrace (m_currentPkt); TransmitStart (); @@ -669,7 +669,7 @@ CsmaNetDevice::Attach (Ptr ch) } void -CsmaNetDevice::SetQueue (Ptr q) +CsmaNetDevice::SetQueue (Ptr > q) { NS_LOG_FUNCTION (q); m_queue = q; @@ -819,7 +819,7 @@ CsmaNetDevice::Receive (Ptr packet, Ptr senderDevice) } } -Ptr +Ptr > CsmaNetDevice::GetQueue (void) const { NS_LOG_FUNCTION_NOARGS (); @@ -970,7 +970,7 @@ CsmaNetDevice::SendFrom (Ptr packet, const Address& src, const Address& // Place the packet to be sent on the send queue. Note that the // queue may fire a drop trace, but we will too. // - if (m_queue->Enqueue (Create (packet)) == false) + if (m_queue->Enqueue (packet) == false) { m_macTxDropTrace (packet); return false; @@ -985,9 +985,9 @@ CsmaNetDevice::SendFrom (Ptr packet, const Address& src, const Address& { if (m_queue->IsEmpty () == false) { - Ptr item = m_queue->Dequeue (); - NS_ASSERT_MSG (item != 0, "CsmaNetDevice::SendFrom(): IsEmpty false but no Packet on queue?"); - m_currentPkt = item->GetPacket (); + Ptr packet = m_queue->Dequeue (); + NS_ASSERT_MSG (packet != 0, "CsmaNetDevice::SendFrom(): IsEmpty false but no Packet on queue?"); + m_currentPkt = packet; m_promiscSnifferTrace (m_currentPkt); m_snifferTrace (m_currentPkt); TransmitStart (); diff --git a/src/csma/model/csma-net-device.h b/src/csma/model/csma-net-device.h index 25bda12b7..99ff9ddb7 100644 --- a/src/csma/model/csma-net-device.h +++ b/src/csma/model/csma-net-device.h @@ -36,7 +36,7 @@ namespace ns3 { -class Queue; +template class Queue; class CsmaChannel; class ErrorModel; @@ -134,14 +134,14 @@ public: * \see DropTailQueue * \param queue a Ptr to the queue for being assigned to the device. */ - void SetQueue (Ptr queue); + void SetQueue (Ptr > queue); /** * Get a copy of the attached Queue. * * \return a pointer to the queue. */ - Ptr GetQueue (void) const; + Ptr > GetQueue (void) const; /** * Attach a receive ErrorModel to the CsmaNetDevice. @@ -530,7 +530,7 @@ private: * \see class Queue * \see class DropTailQueue */ - Ptr m_queue; + Ptr > m_queue; /** * Error model for receive packet events. When active this model will be diff --git a/src/flow-monitor/model/ipv4-flow-probe.cc b/src/flow-monitor/model/ipv4-flow-probe.cc index 3b7fb0b75..aeb82f8b2 100644 --- a/src/flow-monitor/model/ipv4-flow-probe.cc +++ b/src/flow-monitor/model/ipv4-flow-probe.cc @@ -468,7 +468,7 @@ Ipv4FlowProbe::QueueDropLogger (Ptr ipPayload) } void -Ipv4FlowProbe::QueueDiscDropLogger (Ptr item) +Ipv4FlowProbe::QueueDiscDropLogger (Ptr item) { Ipv4FlowProbeTag fTag; bool tagFound = item->GetPacket ()->FindFirstMatchingByteTag (fTag); diff --git a/src/flow-monitor/model/ipv4-flow-probe.h b/src/flow-monitor/model/ipv4-flow-probe.h index 2371a8e05..45a0736b4 100644 --- a/src/flow-monitor/model/ipv4-flow-probe.h +++ b/src/flow-monitor/model/ipv4-flow-probe.h @@ -24,6 +24,7 @@ #include "ns3/flow-probe.h" #include "ns3/ipv4-flow-classifier.h" #include "ns3/ipv4-l3-protocol.h" +#include "ns3/queue-item.h" namespace ns3 { @@ -112,8 +113,8 @@ private: /// \param ipPayload IP payload void QueueDropLogger (Ptr ipPayload); /// Log a packet being dropped by a queue disc - /// \param item queue item - void QueueDiscDropLogger (Ptr item); + /// \param item queue disc item + void QueueDiscDropLogger (Ptr item); Ptr m_classifier; //!< the Ipv4FlowClassifier this probe is associated with Ptr m_ipv4; //!< the Ipv4L3Protocol this probe is bound to diff --git a/src/flow-monitor/model/ipv6-flow-probe.cc b/src/flow-monitor/model/ipv6-flow-probe.cc index 443f1aa45..b509e472f 100644 --- a/src/flow-monitor/model/ipv6-flow-probe.cc +++ b/src/flow-monitor/model/ipv6-flow-probe.cc @@ -412,7 +412,7 @@ Ipv6FlowProbe::QueueDropLogger (Ptr ipPayload) } void -Ipv6FlowProbe::QueueDiscDropLogger (Ptr item) +Ipv6FlowProbe::QueueDiscDropLogger (Ptr item) { Ipv6FlowProbeTag fTag; bool tagFound = item->GetPacket ()->FindFirstMatchingByteTag (fTag); diff --git a/src/flow-monitor/model/ipv6-flow-probe.h b/src/flow-monitor/model/ipv6-flow-probe.h index 071d2b0d3..d3179c948 100644 --- a/src/flow-monitor/model/ipv6-flow-probe.h +++ b/src/flow-monitor/model/ipv6-flow-probe.h @@ -25,6 +25,7 @@ #include "ns3/flow-probe.h" #include "ns3/ipv6-flow-classifier.h" #include "ns3/ipv6-l3-protocol.h" +#include "ns3/queue-item.h" namespace ns3 { @@ -118,8 +119,8 @@ private: /// \param ipPayload IP payload void QueueDropLogger (Ptr ipPayload); /// Log a packet being dropped by a queue disc - /// \param item queue item - void QueueDiscDropLogger (Ptr item); + /// \param item queue disc item + void QueueDiscDropLogger (Ptr item); Ptr m_classifier; //!< the Ipv6FlowClassifier this probe is associated with }; diff --git a/src/internet/model/ipv4-interface.cc b/src/internet/model/ipv4-interface.cc index 392a48854..7ad075eff 100644 --- a/src/internet/model/ipv4-interface.cc +++ b/src/internet/model/ipv4-interface.cc @@ -29,6 +29,7 @@ #include "ns3/packet.h" #include "ns3/node.h" #include "ns3/pointer.h" +#include "ns3/traffic-control-layer.h" namespace ns3 { diff --git a/src/internet/model/ipv4-interface.h b/src/internet/model/ipv4-interface.h index c36a40066..37bff1d07 100644 --- a/src/internet/model/ipv4-interface.h +++ b/src/internet/model/ipv4-interface.h @@ -25,7 +25,6 @@ #include #include "ns3/ptr.h" #include "ns3/object.h" -#include "ns3/traffic-control-layer.h" namespace ns3 { @@ -36,6 +35,7 @@ class ArpCache; class Ipv4InterfaceAddress; class Ipv4Address; class Ipv4Header; +class TrafficControlLayer; /** * \ingroup ipv4 diff --git a/src/internet/model/ipv4-packet-filter.cc b/src/internet/model/ipv4-packet-filter.cc index cca967f18..a01ac4105 100644 --- a/src/internet/model/ipv4-packet-filter.cc +++ b/src/internet/model/ipv4-packet-filter.cc @@ -23,6 +23,7 @@ #include "ns3/log.h" #include "ns3/enum.h" +#include "ns3/uinteger.h" #include "ns3/tcp-header.h" #include "ns3/udp-header.h" #include "ipv4-queue-disc-item.h" diff --git a/src/internet/model/ipv4-queue-disc-item.cc b/src/internet/model/ipv4-queue-disc-item.cc index 283451725..021beb217 100644 --- a/src/internet/model/ipv4-queue-disc-item.cc +++ b/src/internet/model/ipv4-queue-disc-item.cc @@ -31,13 +31,14 @@ Ipv4QueueDiscItem::Ipv4QueueDiscItem (Ptr p, const Address& addr, { } -Ipv4QueueDiscItem::~Ipv4QueueDiscItem() +Ipv4QueueDiscItem::~Ipv4QueueDiscItem () { NS_LOG_FUNCTION (this); } -uint32_t Ipv4QueueDiscItem::GetPacketSize(void) const +uint32_t Ipv4QueueDiscItem::GetSize (void) const { + NS_LOG_FUNCTION (this); Ptr p = GetPacket (); NS_ASSERT (p != 0); uint32_t ret = p->GetSize (); @@ -54,7 +55,7 @@ Ipv4QueueDiscItem::GetHeader (void) const return m_header; } -void Ipv4QueueDiscItem::AddHeader(void) +void Ipv4QueueDiscItem::AddHeader (void) { NS_LOG_FUNCTION (this); diff --git a/src/internet/model/ipv4-queue-disc-item.h b/src/internet/model/ipv4-queue-disc-item.h index 5f0c951c3..76ab26fb2 100644 --- a/src/internet/model/ipv4-queue-disc-item.h +++ b/src/internet/model/ipv4-queue-disc-item.h @@ -20,10 +20,7 @@ #define IPV4_QUEUE_DISC_ITEM_H #include "ns3/packet.h" -#include "ns3/object.h" -#include "ns3/net-device.h" -#include "ns3/traced-value.h" -#include "ns3/queue-disc.h" +#include "ns3/queue-item.h" #include "ipv4-header.h" namespace ns3 { @@ -52,7 +49,7 @@ public: /** * \return the correct packet size (header plus payload). */ - virtual uint32_t GetPacketSize (void) const; + virtual uint32_t GetSize (void) const; /** * \return the header stored in this item.. diff --git a/src/internet/model/ipv6-interface.cc b/src/internet/model/ipv6-interface.cc index b6e4b5a31..3bff0097f 100644 --- a/src/internet/model/ipv6-interface.cc +++ b/src/internet/model/ipv6-interface.cc @@ -24,6 +24,7 @@ #include "ns3/net-device.h" #include "ns3/mac16-address.h" #include "ns3/mac64-address.h" +#include "ns3/traffic-control-layer.h" #include "ipv6-interface.h" #include "ipv6-queue-disc-item.h" diff --git a/src/internet/model/ipv6-interface.h b/src/internet/model/ipv6-interface.h index c6251c27a..2d7e93761 100644 --- a/src/internet/model/ipv6-interface.h +++ b/src/internet/model/ipv6-interface.h @@ -25,7 +25,6 @@ #include "ns3/ptr.h" #include "ns3/object.h" #include "ipv6-interface-address.h" -#include "ns3/traffic-control-layer.h" namespace ns3 { @@ -37,6 +36,7 @@ class NdiscCache; class Ipv6InterfaceAddress; class Ipv6Address; class Ipv6Header; +class TrafficControlLayer; /** * \ingroup ipv6 diff --git a/src/internet/model/ipv6-packet-filter.cc b/src/internet/model/ipv6-packet-filter.cc index abec7999c..7b2433368 100644 --- a/src/internet/model/ipv6-packet-filter.cc +++ b/src/internet/model/ipv6-packet-filter.cc @@ -23,6 +23,7 @@ #include "ns3/log.h" #include "ns3/enum.h" +#include "ns3/uinteger.h" #include "ns3/tcp-header.h" #include "ns3/udp-header.h" #include "ipv6-queue-disc-item.h" diff --git a/src/internet/model/ipv6-queue-disc-item.cc b/src/internet/model/ipv6-queue-disc-item.cc index 50c5547e7..b1e61aaf7 100644 --- a/src/internet/model/ipv6-queue-disc-item.cc +++ b/src/internet/model/ipv6-queue-disc-item.cc @@ -31,13 +31,14 @@ Ipv6QueueDiscItem::Ipv6QueueDiscItem (Ptr p, const Address& addr, { } -Ipv6QueueDiscItem::~Ipv6QueueDiscItem() +Ipv6QueueDiscItem::~Ipv6QueueDiscItem () { NS_LOG_FUNCTION (this); } -uint32_t Ipv6QueueDiscItem::GetPacketSize(void) const +uint32_t Ipv6QueueDiscItem::GetSize (void) const { + NS_LOG_FUNCTION (this); Ptr p = GetPacket (); NS_ASSERT (p != 0); uint32_t ret = p->GetSize (); @@ -54,7 +55,7 @@ Ipv6QueueDiscItem::GetHeader (void) const return m_header; } -void Ipv6QueueDiscItem::AddHeader(void) +void Ipv6QueueDiscItem::AddHeader (void) { NS_LOG_FUNCTION (this); diff --git a/src/internet/model/ipv6-queue-disc-item.h b/src/internet/model/ipv6-queue-disc-item.h index cd58d5f3c..0a4be133f 100644 --- a/src/internet/model/ipv6-queue-disc-item.h +++ b/src/internet/model/ipv6-queue-disc-item.h @@ -20,10 +20,7 @@ #define IPV6_QUEUE_DISC_ITEM_H #include "ns3/packet.h" -#include "ns3/object.h" -#include "ns3/net-device.h" -#include "ns3/traced-value.h" -#include "ns3/queue-disc.h" +#include "ns3/queue-item.h" #include "ipv6-header.h" namespace ns3 { @@ -52,7 +49,7 @@ public: /** * \return the correct packet size (header plus payload). */ - virtual uint32_t GetPacketSize (void) const; + virtual uint32_t GetSize (void) const; /** * \return the header stored in this item.. diff --git a/src/internet/test/tcp-general-test.cc b/src/internet/test/tcp-general-test.cc index b44628e54..87cc7e080 100644 --- a/src/internet/test/tcp-general-test.cc +++ b/src/internet/test/tcp-general-test.cc @@ -24,6 +24,7 @@ #include "ns3/ipv4-address-helper.h" #include "ns3/internet-stack-helper.h" #include "ns3/log.h" +#include "ns3/queue.h" #include "ns3/tcp-l4-protocol.h" #include "../model/ipv4-end-point.h" #include "../model/ipv6-end-point.h" diff --git a/src/internet/test/tcp-slow-start-test.cc b/src/internet/test/tcp-slow-start-test.cc index 9f3a7c069..51fbf06c3 100644 --- a/src/internet/test/tcp-slow-start-test.cc +++ b/src/internet/test/tcp-slow-start-test.cc @@ -19,6 +19,7 @@ #include "ns3/log.h" #include "ns3/test.h" #include "ns3/simple-channel.h" +#include "ns3/node.h" #include "ns3/config.h" #include "ns3/tcp-westwood.h" #include "tcp-general-test.h" diff --git a/src/internet/test/udp-test.cc b/src/internet/test/udp-test.cc index 8f53e3b73..70765100a 100644 --- a/src/internet/test/udp-test.cc +++ b/src/internet/test/udp-test.cc @@ -232,7 +232,7 @@ public: * \brief Adds a packet to the list of sent packets. * \param item The sent packet. */ - void SentPkt (Ptr item); + void SentPkt (Ptr item); }; UdpSocketImplTest::UdpSocketImplTest () @@ -256,7 +256,7 @@ void UdpSocketImplTest::ReceivePkt2 (Ptr socket) NS_ASSERT (availableData == m_receivedPacket2->GetSize ()); } -void UdpSocketImplTest::SentPkt (Ptr item) +void UdpSocketImplTest::SentPkt (Ptr item) { Ptr ipv4Item = DynamicCast (item); NS_TEST_EXPECT_MSG_NE (ipv4Item, 0, "no IPv4 packet"); diff --git a/src/lte/test/lte-simple-net-device.cc b/src/lte/test/lte-simple-net-device.cc index e88bd8303..e1e189676 100644 --- a/src/lte/test/lte-simple-net-device.cc +++ b/src/lte/test/lte-simple-net-device.cc @@ -21,6 +21,7 @@ #include "ns3/simulator.h" #include "ns3/pointer.h" #include "ns3/log.h" +#include "ns3/queue.h" #include "lte-simple-net-device.h" namespace ns3 { diff --git a/src/network/helper/simple-net-device-helper.cc b/src/network/helper/simple-net-device-helper.cc index 397ff7ed9..0c07a3409 100644 --- a/src/network/helper/simple-net-device-helper.cc +++ b/src/network/helper/simple-net-device-helper.cc @@ -22,6 +22,7 @@ #include "ns3/log.h" #include "ns3/simulator.h" #include "ns3/object-factory.h" +#include "ns3/queue.h" #include "ns3/simple-net-device.h" #include "ns3/simple-channel.h" #include "ns3/config.h" @@ -40,7 +41,7 @@ NS_LOG_COMPONENT_DEFINE ("SimpleNetDeviceHelper"); SimpleNetDeviceHelper::SimpleNetDeviceHelper () { - m_queueFactory.SetTypeId ("ns3::DropTailQueue"); + m_queueFactory.SetTypeId ("ns3::DropTailQueue"); m_deviceFactory.SetTypeId ("ns3::SimpleNetDevice"); m_channelFactory.SetTypeId ("ns3::SimpleChannel"); m_pointToPointMode = false; @@ -53,6 +54,8 @@ SimpleNetDeviceHelper::SetQueue (std::string type, std::string n3, const AttributeValue &v3, std::string n4, const AttributeValue &v4) { + QueueBase::AppendItemTypeIfNotPresent (type, "Packet"); + m_queueFactory.SetTypeId (type); m_queueFactory.Set (n1, v1); m_queueFactory.Set (n2, v2); @@ -134,7 +137,7 @@ SimpleNetDeviceHelper::InstallPriv (Ptr node, Ptr channel) device->SetAddress (Mac48Address::Allocate ()); node->AddDevice (device); device->SetChannel (channel); - Ptr queue = m_queueFactory.Create (); + Ptr > queue = m_queueFactory.Create > (); device->SetQueue (queue); NS_ASSERT_MSG (!m_pointToPointMode || (channel->GetNDevices () <= 2), "Device set to PointToPoint and more than 2 devices on the channel."); return device; diff --git a/src/network/model/net-device.cc b/src/network/model/net-device.cc index 419cfdab7..b54c619c4 100644 --- a/src/network/model/net-device.cc +++ b/src/network/model/net-device.cc @@ -18,253 +18,13 @@ * Author: Mathieu Lacage */ -#include "ns3/object.h" #include "ns3/log.h" -#include "ns3/abort.h" -#include "ns3/uinteger.h" -#include "ns3/queue-limits.h" #include "net-device.h" -#include "packet.h" namespace ns3 { NS_LOG_COMPONENT_DEFINE ("NetDevice"); -QueueItem::QueueItem (Ptr p) -{ - m_packet = p; -} - -QueueItem::~QueueItem() -{ - NS_LOG_FUNCTION (this); - m_packet = 0; -} - -Ptr -QueueItem::GetPacket (void) const -{ - return m_packet; -} - -uint32_t -QueueItem::GetPacketSize (void) const -{ - NS_ASSERT (m_packet != 0); - return m_packet->GetSize (); -} - -bool -QueueItem::GetUint8Value (QueueItem::Uint8Values field, uint8_t& value) const -{ - return false; -} - -void -QueueItem::Print (std::ostream& os) const -{ - os << GetPacket(); -} - -std::ostream & operator << (std::ostream &os, const QueueItem &item) -{ - item.Print (os); - return os; -} - -NetDeviceQueue::NetDeviceQueue() - : m_stoppedByDevice (false), - m_stoppedByQueueLimits (false) -{ - NS_LOG_FUNCTION (this); -} - -NetDeviceQueue::~NetDeviceQueue () -{ - NS_LOG_FUNCTION (this); -} - -bool -NetDeviceQueue::IsStopped (void) const -{ - return m_stoppedByDevice || m_stoppedByQueueLimits; -} - -void -NetDeviceQueue::Start (void) -{ - m_stoppedByDevice = false; -} - -void -NetDeviceQueue::Stop (void) -{ - m_stoppedByDevice = true; -} - -void -NetDeviceQueue::Wake (void) -{ - Start (); - - // Request the queue disc to dequeue a packet - if (!m_wakeCallback.IsNull ()) - { - m_wakeCallback (); - } -} - -void -NetDeviceQueue::SetWakeCallback (WakeCallback cb) -{ - m_wakeCallback = cb; -} - -void -NetDeviceQueue::NotifyQueuedBytes (uint32_t bytes) -{ - NS_LOG_FUNCTION (this << bytes); - if (!m_queueLimits) - { - return; - } - m_queueLimits->Queued (bytes); - if (m_queueLimits->Available () >= 0) - { - return; - } - m_stoppedByQueueLimits = true; -} - -void -NetDeviceQueue::NotifyTransmittedBytes (uint32_t bytes) -{ - NS_LOG_FUNCTION (this << bytes); - if ((!m_queueLimits) || (!bytes)) - { - return; - } - m_queueLimits->Completed (bytes); - if (m_queueLimits->Available () < 0) - { - return; - } - m_stoppedByQueueLimits = false; - // Request the queue disc to dequeue a packet - if (!m_wakeCallback.IsNull ()) - { - m_wakeCallback (); - } -} - -void -NetDeviceQueue::ResetQueueLimits () -{ - NS_LOG_FUNCTION (this); - if (!m_queueLimits) - { - return; - } - m_queueLimits->Reset (); -} - -void -NetDeviceQueue::SetQueueLimits (Ptr ql) -{ - NS_LOG_FUNCTION (this << ql); - m_queueLimits = ql; -} - -Ptr -NetDeviceQueue::GetQueueLimits () -{ - NS_LOG_FUNCTION (this); - return m_queueLimits; -} - - -NS_OBJECT_ENSURE_REGISTERED (NetDeviceQueueInterface); - -TypeId NetDeviceQueueInterface::GetTypeId (void) -{ - static TypeId tid = TypeId ("ns3::NetDeviceQueueInterface") - .SetParent () - .SetGroupName("Network") - ; - return tid; -} - -NetDeviceQueueInterface::NetDeviceQueueInterface () - : m_numTxQueues (1) -{ - NS_LOG_FUNCTION (this); -} - -NetDeviceQueueInterface::~NetDeviceQueueInterface () -{ - NS_LOG_FUNCTION (this); -} - -Ptr -NetDeviceQueueInterface::GetTxQueue (uint8_t i) const -{ - NS_ASSERT (i < m_txQueuesVector.size ()); - return m_txQueuesVector[i]; -} - -uint8_t -NetDeviceQueueInterface::GetNTxQueues (void) const -{ - return m_txQueuesVector.size (); -} - -void -NetDeviceQueueInterface::DoDispose (void) -{ - NS_LOG_FUNCTION (this); - m_txQueuesVector.clear (); - Object::DoDispose (); -} - -void -NetDeviceQueueInterface::SetTxQueuesN (uint8_t numTxQueues) -{ - NS_LOG_FUNCTION (this << numTxQueues); - NS_ASSERT (numTxQueues > 0); - - NS_ABORT_MSG_IF (m_txQueuesVector.size (), "Cannot change the number of" - " device transmission queues once they have been created."); - - m_numTxQueues = numTxQueues; -} - -void -NetDeviceQueueInterface::CreateTxQueues (void) -{ - NS_LOG_FUNCTION (this); - - NS_ABORT_MSG_IF (m_txQueuesVector.size (), "The device transmission queues" - " have been already created."); - - for (uint8_t i = 0; i < m_numTxQueues; i++) - { - Ptr devQueue = Create (); - m_txQueuesVector.push_back (devQueue); - } -} - -void -NetDeviceQueueInterface::SetSelectQueueCallback (SelectQueueCallback cb) -{ - m_selectQueueCallback = cb; -} - -NetDeviceQueueInterface::SelectQueueCallback -NetDeviceQueueInterface::GetSelectQueueCallback (void) const -{ - return m_selectQueueCallback; -} - NS_OBJECT_ENSURE_REGISTERED (NetDevice); TypeId NetDevice::GetTypeId (void) diff --git a/src/network/model/net-device.h b/src/network/model/net-device.h index 9318eda6b..f4363669b 100644 --- a/src/network/model/net-device.h +++ b/src/network/model/net-device.h @@ -17,17 +17,15 @@ * * Author: Mathieu Lacage * Modified by Emmanuelle Laprise to remove dependence on LLC headers - * Modified by Stefano Avallone to add NetDeviceQueue and NetDeviceQueueInterface */ #ifndef NET_DEVICE_H #define NET_DEVICE_H -#include -#include #include #include "ns3/callback.h" #include "ns3/object.h" #include "ns3/ptr.h" +#include "packet.h" #include "address.h" #include "ns3/ipv4-address.h" #include "ns3/ipv6-address.h" @@ -36,315 +34,12 @@ namespace ns3 { class Node; class Channel; -class Packet; -class QueueLimits; /** * \ingroup network * \defgroup netdevice Network Device */ -/** - * \ingroup netdevice - * \brief Base class to represent items of packet Queues - * - * An item stored in an ns-3 packet Queue contains a packet and possibly other - * information. An item of the base class only contains a packet. Subclasses - * can be derived from this base class to allow items to contain additional - * information. - */ -class QueueItem : public SimpleRefCount -{ -public: - /** - * \brief Create a queue item containing a packet. - * \param p the packet included in the created item. - */ - QueueItem (Ptr p); - - virtual ~QueueItem (); - - /** - * \return the packet included in this item. - */ - Ptr GetPacket (void) const; - - /** - * \brief Use this method (instead of GetPacket ()->GetSize ()) to get the packet size - * - * Subclasses may keep header and payload separate to allow manipulating the header, - * so using this method ensures that the correct packet size is returned. - * - * \return the size of the packet included in this item. - */ - virtual uint32_t GetPacketSize (void) const; - - /** - * \enum Uint8Values - * \brief 1-byte fields of the packet whose value can be retrieved, if present - */ - enum Uint8Values - { - IP_DSFIELD - }; - - /** - * \brief Retrieve the value of a given field from the packet, if present - * \param field the field whose value has to be retrieved - * \param value the output parameter to store the retrieved value - * - * \return true if the requested field is present in the packet, false otherwise. - */ - virtual bool GetUint8Value (Uint8Values field, uint8_t &value) const; - - /** - * \brief Print the item contents. - * \param os output stream in which the data should be printed. - */ - virtual void Print (std::ostream &os) const; - - /** - * TracedCallback signature for Ptr - * - * \param [in] item The queue item. - */ - typedef void (* TracedCallback) (Ptr item); - -private: - /** - * \brief Default constructor - * - * Defined and unimplemented to avoid misuse - */ - QueueItem (); - /** - * \brief Copy constructor - * - * Defined and unimplemented to avoid misuse - */ - QueueItem (const QueueItem &); - /** - * \brief Assignment operator - * - * Defined and unimplemented to avoid misuse - * \returns - */ - QueueItem &operator = (const QueueItem &); - - /** - * The packet contained in the queue item. - */ - Ptr m_packet; -}; - -/** - * \brief Stream insertion operator. - * - * \param os the stream - * \param item the item - * \returns a reference to the stream - */ -std::ostream& operator<< (std::ostream& os, const QueueItem &item); - -/** - * \ingroup netdevice - * - * \brief Network device transmission queue - * - * This class stores information about a single transmission queue - * of a network device that is exposed to queue discs. Such information - * includes the state of the transmission queue (whether it has been - * stopped or not) and data used by techniques such as Byte Queue Limits. - * - * This class roughly models the struct netdev_queue of Linux. - */ -class NetDeviceQueue : public SimpleRefCount -{ -public: - NetDeviceQueue (); - virtual ~NetDeviceQueue(); - - /** - * Called by the device to start this device transmission queue. - * This is the analogous to the netif_tx_start_queue function of the Linux kernel. - */ - virtual void Start (void); - - /** - * Called by the device to stop this device transmission queue. - * This is the analogous to the netif_tx_stop_queue function of the Linux kernel. - */ - virtual void Stop (void); - - /** - * Called by the device to wake the queue disc associated with this - * device transmission queue. This is done by invoking the wake callback. - * This is the analogous to the netif_tx_wake_queue function of the Linux kernel. - */ - virtual void Wake (void); - - /** - * \brief Get the status of the device transmission queue. - * \return true if the device transmission queue is stopped. - * - * Called by queue discs to enquire about the status of a given transmission queue. - * This is the analogous to the netif_tx_queue_stopped function of the Linux kernel. - */ - bool IsStopped (void) const; - - /// Callback invoked by netdevices to wake upper layers - typedef Callback< void > WakeCallback; - - /** - * \brief Set the wake callback - * \param cb the callback to set - * - * Called by the traffic control layer to set the wake callback. The wake callback - * is invoked by the device whenever it is needed to "wake" the upper layers (i.e., - * solicitate the queue disc associated with this transmission queue (in case of - * multi-queue aware queue discs) or to the network device (otherwise) to send - * packets down to the device). - */ - virtual void SetWakeCallback (WakeCallback cb); - - /** - * \brief Called by the netdevice to report the number of bytes queued to the device queue - * \param bytes number of bytes queued to the device queue - */ - void NotifyQueuedBytes (uint32_t bytes); - - /** - * \brief Called by the netdevice to report the number of bytes it is going to transmit - * \param bytes number of bytes the device is going to transmit - */ - void NotifyTransmittedBytes (uint32_t bytes); - - /** - * \brief Reset queue limits state - */ - void ResetQueueLimits (); - - /** - * \brief Set queue limits to this queue - * \param ql the queue limits associated to this queue - */ - void SetQueueLimits (Ptr ql); - - /** - * \brief Get queue limits to this queue - * \return the queue limits associated to this queue - */ - Ptr GetQueueLimits (); - -private: - bool m_stoppedByDevice; //!< True if the queue has been stopped by the device - bool m_stoppedByQueueLimits; //!< True if the queue has been stopped by a queue limits object - Ptr m_queueLimits; //!< Queue limits object - WakeCallback m_wakeCallback; //!< Wake callback -}; - - -/** - * \ingroup netdevice - * - * \brief Network device transmission queue interface - * - * This interface is used by the traffic control layer and by the aggregated - * device to access the transmission queues of the device. Additionally, through - * this interface, traffic control aware netdevices can: - * - set the number of transmission queues - * - set the method used (by upper layers) to determine the transmission queue - * in which the netdevice would enqueue a given packet - * This interface is created and aggregated to a device by the traffic control - * layer when an Ipv{4,6}Interface is added to the device or a queue disc is - * installed on the device. - */ -class NetDeviceQueueInterface : public Object -{ -public: - /** - * \brief Get the type ID. - * \return the object TypeId - */ - static TypeId GetTypeId (void); - - /** - * \brief Constructor - * - * Creates one NetDeviceQueue by default - */ - NetDeviceQueueInterface (); - virtual ~NetDeviceQueueInterface (); - - /** - * \brief Get the i-th transmission queue of the device. - * - * \param i the index of the requested queue. - * \return the i-th transmission queue of the device. - * - * The index of the first transmission queue is zero. - */ - Ptr GetTxQueue (uint8_t i) const; - - /** - * \brief Get the number of device transmission queues. - * \return the number of device transmission queues. - */ - uint8_t GetNTxQueues (void) const; - - /** - * \brief Set the number of device transmission queues to create. - * \param numTxQueues number of device transmission queues to create. - * - * A multi-queue netdevice must call this method from within its - * NotifyNewAggregate method to set the number of device transmission queues - * to create. - */ - void SetTxQueuesN (uint8_t numTxQueues); - - /** - * \brief Create the device transmission queues. - * - * Called by the traffic control layer just after aggregating this netdevice - * queue interface to the netdevice. - */ - void CreateTxQueues (void); - - /// Callback invoked to determine the tx queue selected for a given packet - typedef Callback< uint8_t, Ptr > SelectQueueCallback; - - /** - * \brief Set the select queue callback. - * \param cb the callback to set. - * - * A multi-queue netdevice must call this method from within its - * NotifyNewAggregate method to set the select queue callback, i.e., the - * method used to select a device transmission queue for a given packet. - */ - void SetSelectQueueCallback (SelectQueueCallback cb); - - /** - * \brief Get the select queue callback. - * \return the select queue callback. - * - * Called by the traffic control layer to get the select queue callback set - * by a multi-queue device. - */ - SelectQueueCallback GetSelectQueueCallback (void) const; - -protected: - /** - * \brief Dispose of the object - */ - virtual void DoDispose (void); - -private: - std::vector< Ptr > m_txQueuesVector; //!< Device transmission queues - SelectQueueCallback m_selectQueueCallback; //!< Select queue callback - uint8_t m_numTxQueues; //!< Number of transmission queues to create -}; - - /** * \ingroup netdevice * diff --git a/src/network/test/drop-tail-queue-test-suite.cc b/src/network/test/drop-tail-queue-test-suite.cc index 1edb03b98..a98210ef5 100644 --- a/src/network/test/drop-tail-queue-test-suite.cc +++ b/src/network/test/drop-tail-queue-test-suite.cc @@ -36,7 +36,7 @@ DropTailQueueTestCase::DropTailQueueTestCase () void DropTailQueueTestCase::DoRun (void) { - Ptr queue = CreateObject (); + Ptr > queue = CreateObject > (); NS_TEST_EXPECT_MSG_EQ (queue->SetAttributeFailSafe ("MaxPackets", UintegerValue (3)), true, "Verify that we can actually set the attribute"); @@ -47,34 +47,34 @@ DropTailQueueTestCase::DoRun (void) p4 = Create (); NS_TEST_EXPECT_MSG_EQ (queue->GetNPackets (), 0, "There should be no packets in there"); - queue->Enqueue (Create (p1)); + queue->Enqueue (p1); NS_TEST_EXPECT_MSG_EQ (queue->GetNPackets (), 1, "There should be one packet in there"); - queue->Enqueue (Create (p2)); + queue->Enqueue (p2); NS_TEST_EXPECT_MSG_EQ (queue->GetNPackets (), 2, "There should be two packets in there"); - queue->Enqueue (Create (p3)); + queue->Enqueue (p3); NS_TEST_EXPECT_MSG_EQ (queue->GetNPackets (), 3, "There should be three packets in there"); - queue->Enqueue (Create (p4)); // will be dropped + queue->Enqueue (p4); // will be dropped NS_TEST_EXPECT_MSG_EQ (queue->GetNPackets (), 3, "There should be still three packets in there"); - Ptr item; + Ptr packet; - item = queue->Dequeue (); - NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the first packet"); + packet = queue->Dequeue (); + NS_TEST_EXPECT_MSG_EQ ((packet != 0), true, "I want to remove the first packet"); NS_TEST_EXPECT_MSG_EQ (queue->GetNPackets (), 2, "There should be two packets in there"); - NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p1->GetUid (), "was this the first packet ?"); + NS_TEST_EXPECT_MSG_EQ (packet->GetUid (), p1->GetUid (), "was this the first packet ?"); - item = queue->Dequeue (); - NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the second packet"); + packet = queue->Dequeue (); + NS_TEST_EXPECT_MSG_EQ ((packet != 0), true, "I want to remove the second packet"); NS_TEST_EXPECT_MSG_EQ (queue->GetNPackets (), 1, "There should be one packet in there"); - NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p2->GetUid (), "Was this the second packet ?"); + NS_TEST_EXPECT_MSG_EQ (packet->GetUid (), p2->GetUid (), "Was this the second packet ?"); - item = queue->Dequeue (); - NS_TEST_EXPECT_MSG_EQ ((item != 0), true, "I want to remove the third packet"); + packet = queue->Dequeue (); + NS_TEST_EXPECT_MSG_EQ ((packet != 0), true, "I want to remove the third packet"); NS_TEST_EXPECT_MSG_EQ (queue->GetNPackets (), 0, "There should be no packets in there"); - NS_TEST_EXPECT_MSG_EQ (item->GetPacket ()->GetUid (), p3->GetUid (), "Was this the third packet ?"); + NS_TEST_EXPECT_MSG_EQ (packet->GetUid (), p3->GetUid (), "Was this the third packet ?"); - item = queue->Dequeue (); - NS_TEST_EXPECT_MSG_EQ ((item == 0), true, "There are really no packets in there"); + packet = queue->Dequeue (); + NS_TEST_EXPECT_MSG_EQ ((packet == 0), true, "There are really no packets in there"); } static class DropTailQueueTestSuite : public TestSuite diff --git a/src/network/utils/drop-tail-queue.cc b/src/network/utils/drop-tail-queue.cc index 084164c3b..ef417e81a 100644 --- a/src/network/utils/drop-tail-queue.cc +++ b/src/network/utils/drop-tail-queue.cc @@ -16,84 +16,10 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "ns3/log.h" #include "drop-tail-queue.h" namespace ns3 { -NS_LOG_COMPONENT_DEFINE ("DropTailQueue"); - -NS_OBJECT_ENSURE_REGISTERED (DropTailQueue); - -TypeId DropTailQueue::GetTypeId (void) -{ - static TypeId tid = TypeId ("ns3::DropTailQueue") - .SetParent () - .SetGroupName ("Network") - .AddConstructor () - ; - return tid; -} - -DropTailQueue::DropTailQueue () : - Queue (), - m_packets () -{ - NS_LOG_FUNCTION (this); -} - -DropTailQueue::~DropTailQueue () -{ - NS_LOG_FUNCTION (this); -} - -bool -DropTailQueue::DoEnqueue (Ptr item) -{ - NS_LOG_FUNCTION (this << item); - NS_ASSERT (m_packets.size () == GetNPackets ()); - - m_packets.push (item); - - return true; -} - -Ptr -DropTailQueue::DoDequeue (void) -{ - NS_LOG_FUNCTION (this); - NS_ASSERT (m_packets.size () == GetNPackets ()); - - Ptr item = m_packets.front (); - m_packets.pop (); - - NS_LOG_LOGIC ("Popped " << item); - - return item; -} - -Ptr -DropTailQueue::DoRemove (void) -{ - NS_LOG_FUNCTION (this); - NS_ASSERT (m_packets.size () == GetNPackets ()); - - Ptr item = m_packets.front (); - m_packets.pop (); - - NS_LOG_LOGIC ("Removed " << item); - - return item; -} - -Ptr -DropTailQueue::DoPeek (void) const -{ - NS_LOG_FUNCTION (this); - NS_ASSERT (m_packets.size () == GetNPackets ()); - - return m_packets.front (); -} +NS_OBJECT_TEMPLATE_CLASS_DEFINE (DropTailQueue,Packet); } // namespace ns3 - diff --git a/src/network/utils/drop-tail-queue.h b/src/network/utils/drop-tail-queue.h index 9b4c4893b..2c2484ef5 100644 --- a/src/network/utils/drop-tail-queue.h +++ b/src/network/utils/drop-tail-queue.h @@ -29,7 +29,8 @@ namespace ns3 { * * \brief A FIFO packet queue that drops tail-end packets on overflow */ -class DropTailQueue : public Queue +template +class DropTailQueue : public Queue { public: /** @@ -44,17 +45,100 @@ public: */ DropTailQueue (); - virtual ~DropTailQueue(); + virtual ~DropTailQueue (); private: - virtual bool DoEnqueue (Ptr item); - virtual Ptr DoDequeue (void); - virtual Ptr DoRemove (void); - virtual Ptr DoPeek (void) const; + virtual bool DoEnqueue (Ptr item); + virtual Ptr DoDequeue (void); + virtual Ptr DoRemove (void); + virtual Ptr DoPeek (void) const; - std::queue > m_packets; //!< the items in the queue + std::queue > m_packets; //!< the items in the queue }; + +/** + * Implementation of the templates declared above. + */ + +template +TypeId +DropTailQueue::GetTypeId (void) +{ + static TypeId tid = TypeId (("ns3::DropTailQueue<" + GetTypeParamName > () + ">").c_str ()) + .SetParent > () + .SetGroupName ("Network") + .template AddConstructor > () + ; + return tid; +} + +template +DropTailQueue::DropTailQueue () : + Queue (), + m_packets () +{ + QUEUE_LOG (LOG_LOGIC, "DropTailQueue(" << this << ")"); +} + +template +DropTailQueue::~DropTailQueue () +{ + QUEUE_LOG (LOG_LOGIC, "~DropTailQueue(" << this << ")"); +} + +template +bool +DropTailQueue::DoEnqueue (Ptr item) +{ + QUEUE_LOG (LOG_LOGIC, "DropTailQueue:DoEnqueue(" << this << ", " << item << ")"); + NS_ASSERT (m_packets.size () == this->GetNPackets ()); + + m_packets.push (item); + + return true; +} + +template +Ptr +DropTailQueue::DoDequeue (void) +{ + QUEUE_LOG (LOG_LOGIC, "DropTailQueue:DoDequeue(" << this << ")"); + NS_ASSERT (m_packets.size () == this->GetNPackets ()); + + Ptr item = m_packets.front (); + m_packets.pop (); + + QUEUE_LOG (LOG_LOGIC, "Popped " << item); + + return item; +} + +template +Ptr +DropTailQueue::DoRemove (void) +{ + QUEUE_LOG (LOG_LOGIC, "DropTailQueue:DoRemove(" << this << ")"); + NS_ASSERT (m_packets.size () == this->GetNPackets ()); + + Ptr item = m_packets.front (); + m_packets.pop (); + + QUEUE_LOG (LOG_LOGIC, "Removed " << item); + + return item; +} + +template +Ptr +DropTailQueue::DoPeek (void) const +{ + QUEUE_LOG (LOG_LOGIC, "DropTailQueue:DoPeek(" << this << ")"); + NS_ASSERT (m_packets.size () == this->GetNPackets ()); + + return m_packets.front (); +} + } // namespace ns3 #endif /* DROPTAIL_H */ diff --git a/src/network/utils/net-device-queue-interface.cc b/src/network/utils/net-device-queue-interface.cc new file mode 100644 index 000000000..198e167fa --- /dev/null +++ b/src/network/utils/net-device-queue-interface.cc @@ -0,0 +1,246 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2017 Universita' degli Studi di Napoli Federico II + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Stefano Avallone + */ + +#include "ns3/log.h" +#include "ns3/abort.h" +#include "ns3/queue-limits.h" +#include "ns3/net-device-queue-interface.h" +#include "ns3/simulator.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("NetDeviceQueueInterface"); + +NetDeviceQueue::NetDeviceQueue () + : m_stoppedByDevice (false), + m_stoppedByQueueLimits (false) +{ + NS_LOG_FUNCTION (this); +} + +NetDeviceQueue::~NetDeviceQueue () +{ + NS_LOG_FUNCTION (this); +} + +bool +NetDeviceQueue::IsStopped (void) const +{ + NS_LOG_FUNCTION (this); + return m_stoppedByDevice || m_stoppedByQueueLimits; +} + +void +NetDeviceQueue::Start (void) +{ + NS_LOG_FUNCTION (this); + m_stoppedByDevice = false; +} + +void +NetDeviceQueue::Stop (void) +{ + NS_LOG_FUNCTION (this); + m_stoppedByDevice = true; +} + +void +NetDeviceQueue::Wake (void) +{ + NS_LOG_FUNCTION (this); + + bool wasStoppedByDevice = m_stoppedByDevice; + m_stoppedByDevice = false; + + // Request the queue disc to dequeue a packet + if (wasStoppedByDevice && !m_wakeCallback.IsNull ()) + { + Simulator::ScheduleNow (&NetDeviceQueue::m_wakeCallback, this); + } +} + +void +NetDeviceQueue::SetWakeCallback (WakeCallback cb) +{ + m_wakeCallback = cb; +} + +void +NetDeviceQueue::NotifyQueuedBytes (uint32_t bytes) +{ + NS_LOG_FUNCTION (this << bytes); + if (!m_queueLimits) + { + return; + } + m_queueLimits->Queued (bytes); + if (m_queueLimits->Available () >= 0) + { + return; + } + m_stoppedByQueueLimits = true; +} + +void +NetDeviceQueue::NotifyTransmittedBytes (uint32_t bytes) +{ + NS_LOG_FUNCTION (this << bytes); + if ((!m_queueLimits) || (!bytes)) + { + return; + } + m_queueLimits->Completed (bytes); + if (m_queueLimits->Available () < 0) + { + return; + } + bool wasStoppedByQueueLimits = m_stoppedByQueueLimits; + m_stoppedByQueueLimits = false; + // Request the queue disc to dequeue a packet + if (wasStoppedByQueueLimits && !m_wakeCallback.IsNull ()) + { + Simulator::ScheduleNow (&NetDeviceQueue::m_wakeCallback, this); + } +} + +void +NetDeviceQueue::ResetQueueLimits () +{ + NS_LOG_FUNCTION (this); + if (!m_queueLimits) + { + return; + } + m_queueLimits->Reset (); +} + +void +NetDeviceQueue::SetQueueLimits (Ptr ql) +{ + NS_LOG_FUNCTION (this << ql); + m_queueLimits = ql; +} + +Ptr +NetDeviceQueue::GetQueueLimits () +{ + NS_LOG_FUNCTION (this); + return m_queueLimits; +} + + +NS_OBJECT_ENSURE_REGISTERED (NetDeviceQueueInterface); + +TypeId NetDeviceQueueInterface::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::NetDeviceQueueInterface") + .SetParent () + .SetGroupName("Network") + .AddConstructor () + ; + return tid; +} + +NetDeviceQueueInterface::NetDeviceQueueInterface () + : m_numTxQueues (1), + m_lateTxQueuesCreation (false) +{ + NS_LOG_FUNCTION (this); +} + +NetDeviceQueueInterface::~NetDeviceQueueInterface () +{ + NS_LOG_FUNCTION (this); +} + +Ptr +NetDeviceQueueInterface::GetTxQueue (uint8_t i) const +{ + NS_ASSERT (i < m_txQueuesVector.size ()); + return m_txQueuesVector[i]; +} + +uint8_t +NetDeviceQueueInterface::GetNTxQueues (void) const +{ + return m_txQueuesVector.size (); +} + +void +NetDeviceQueueInterface::DoDispose (void) +{ + NS_LOG_FUNCTION (this); + m_txQueuesVector.clear (); + Object::DoDispose (); +} + +void +NetDeviceQueueInterface::SetTxQueuesN (uint8_t numTxQueues) +{ + NS_LOG_FUNCTION (this << numTxQueues); + NS_ASSERT (numTxQueues > 0); + + NS_ABORT_MSG_IF (m_txQueuesVector.size (), "Cannot change the number of" + " device transmission queues once they have been created."); + + m_numTxQueues = numTxQueues; +} + +void +NetDeviceQueueInterface::CreateTxQueues (void) +{ + NS_LOG_FUNCTION (this); + + NS_ABORT_MSG_IF (m_txQueuesVector.size (), "The device transmission queues" + " have been already created."); + + for (uint8_t i = 0; i < m_numTxQueues; i++) + { + Ptr devQueue = Create (); + m_txQueuesVector.push_back (devQueue); + } +} + +bool +NetDeviceQueueInterface::GetLateTxQueuesCreation (void) const +{ + return m_lateTxQueuesCreation; +} + +void +NetDeviceQueueInterface::SetLateTxQueuesCreation (bool value) +{ + NS_LOG_FUNCTION (this << value); + m_lateTxQueuesCreation = value; +} + +void +NetDeviceQueueInterface::SetSelectQueueCallback (SelectQueueCallback cb) +{ + m_selectQueueCallback = cb; +} + +NetDeviceQueueInterface::SelectQueueCallback +NetDeviceQueueInterface::GetSelectQueueCallback (void) const +{ + return m_selectQueueCallback; +} + +} // namespace ns3 diff --git a/src/network/utils/net-device-queue-interface.h b/src/network/utils/net-device-queue-interface.h new file mode 100644 index 000000000..343388658 --- /dev/null +++ b/src/network/utils/net-device-queue-interface.h @@ -0,0 +1,257 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2017 Universita' degli Studi di Napoli Federico II + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Stefano Avallone + */ +#ifndef NET_DEVICE_QUEUE_INTERFACE_H +#define NET_DEVICE_QUEUE_INTERFACE_H + +#include +#include "ns3/callback.h" +#include "ns3/object.h" +#include "ns3/ptr.h" +#include "ns3/queue-item.h" + +namespace ns3 { + +class QueueLimits; + +/** + * \ingroup network + * \defgroup netdevice Network Device + */ + +/** + * \ingroup netdevice + * + * \brief Network device transmission queue + * + * This class stores information about a single transmission queue + * of a network device that is exposed to queue discs. Such information + * includes the state of the transmission queue (whether it has been + * stopped or not) and data used by techniques such as Byte Queue Limits. + * + * This class roughly models the struct netdev_queue of Linux. + */ +class NetDeviceQueue : public SimpleRefCount +{ +public: + NetDeviceQueue (); + virtual ~NetDeviceQueue(); + + /** + * Called by the device to start this device transmission queue. + * This is the analogous to the netif_tx_start_queue function of the Linux kernel. + */ + virtual void Start (void); + + /** + * Called by the device to stop this device transmission queue. + * This is the analogous to the netif_tx_stop_queue function of the Linux kernel. + */ + virtual void Stop (void); + + /** + * Called by the device to wake the queue disc associated with this + * device transmission queue. This is done by invoking the wake callback. + * This is the analogous to the netif_tx_wake_queue function of the Linux kernel. + */ + virtual void Wake (void); + + /** + * \brief Get the status of the device transmission queue. + * \return true if the device transmission queue is stopped. + * + * Called by queue discs to enquire about the status of a given transmission queue. + * This is the analogous to the netif_xmit_stopped function of the Linux kernel. + */ + bool IsStopped (void) const; + + /// Callback invoked by netdevices to wake upper layers + typedef Callback< void > WakeCallback; + + /** + * \brief Set the wake callback + * \param cb the callback to set + * + * Called by the traffic control layer to set the wake callback. The wake callback + * is invoked by the device whenever it is needed to "wake" the upper layers (i.e., + * solicitate the queue disc associated with this transmission queue (in case of + * multi-queue aware queue discs) or to the network device (otherwise) to send + * packets down to the device). + */ + virtual void SetWakeCallback (WakeCallback cb); + + /** + * \brief Called by the netdevice to report the number of bytes queued to the device queue + * \param bytes number of bytes queued to the device queue + */ + void NotifyQueuedBytes (uint32_t bytes); + + /** + * \brief Called by the netdevice to report the number of bytes it is going to transmit + * \param bytes number of bytes the device is going to transmit + */ + void NotifyTransmittedBytes (uint32_t bytes); + + /** + * \brief Reset queue limits state + */ + void ResetQueueLimits (); + + /** + * \brief Set queue limits to this queue + * \param ql the queue limits associated to this queue + */ + void SetQueueLimits (Ptr ql); + + /** + * \brief Get queue limits to this queue + * \return the queue limits associated to this queue + */ + Ptr GetQueueLimits (); + +private: + bool m_stoppedByDevice; //!< True if the queue has been stopped by the device + bool m_stoppedByQueueLimits; //!< True if the queue has been stopped by a queue limits object + Ptr m_queueLimits; //!< Queue limits object + WakeCallback m_wakeCallback; //!< Wake callback +}; + + +/** + * \ingroup netdevice + * + * \brief Network device transmission queue interface + * + * This interface is used by the traffic control layer and by the aggregated + * device to access the transmission queues of the device. Additionally, through + * this interface, traffic control aware netdevices can: + * - set the number of transmission queues + * - set the method used (by upper layers) to determine the transmission queue + * in which the netdevice would enqueue a given packet + * This interface is created and aggregated to a device by the traffic control + * layer when an Ipv{4,6}Interface is added to the device or a queue disc is + * installed on the device. + */ +class NetDeviceQueueInterface : public Object +{ +public: + /** + * \brief Get the type ID. + * \return the object TypeId + */ + static TypeId GetTypeId (void); + + /** + * \brief Constructor + * + * Creates one NetDeviceQueue by default + */ + NetDeviceQueueInterface (); + virtual ~NetDeviceQueueInterface (); + + /** + * \brief Get the i-th transmission queue of the device. + * + * \param i the index of the requested queue. + * \return the i-th transmission queue of the device. + * + * The index of the first transmission queue is zero. + */ + Ptr GetTxQueue (uint8_t i) const; + + /** + * \brief Get the number of device transmission queues. + * \return the number of device transmission queues. + */ + uint8_t GetNTxQueues (void) const; + + /** + * \brief Set the number of device transmission queues to create. + * \param numTxQueues number of device transmission queues to create. + * + * A multi-queue netdevice must call this method from within its + * NotifyNewAggregate method to set the number of device transmission queues + * to create. + */ + void SetTxQueuesN (uint8_t numTxQueues); + + /** + * \brief Create the device transmission queues. + * + * Called by the traffic control layer just after aggregating this netdevice + * queue interface to the netdevice. + */ + void CreateTxQueues (void); + + /** + * \brief Get the value of the late TX queues creation flag. + * \return the value of the late TX queues creation flag. + */ + bool GetLateTxQueuesCreation (void) const; + + /** + * \brief Set the late TX queues creation flag. + * \param value the boolean value + * + * By default, the late TX queues creation flag is false, which leads the + * traffic control layer to create the TX queues right after the netdevice + * queue interface is aggregated to the device. Netdevices that want to + * explicitly create TX queues at a later stage need to set this flag to + * true in the NotifyNewAggregate method. + */ + void SetLateTxQueuesCreation (bool value); + + /// Callback invoked to determine the tx queue selected for a given packet + typedef Callback< uint8_t, Ptr > SelectQueueCallback; + + /** + * \brief Set the select queue callback. + * \param cb the callback to set. + * + * A multi-queue netdevice must call this method from within its + * NotifyNewAggregate method to set the select queue callback, i.e., the + * method used to select a device transmission queue for a given packet. + */ + void SetSelectQueueCallback (SelectQueueCallback cb); + + /** + * \brief Get the select queue callback. + * \return the select queue callback. + * + * Called by the traffic control layer to get the select queue callback set + * by a multi-queue device. + */ + SelectQueueCallback GetSelectQueueCallback (void) const; + +protected: + /** + * \brief Dispose of the object + */ + virtual void DoDispose (void); + +private: + std::vector< Ptr > m_txQueuesVector; //!< Device transmission queues + SelectQueueCallback m_selectQueueCallback; //!< Select queue callback + uint8_t m_numTxQueues; //!< Number of transmission queues to create + bool m_lateTxQueuesCreation; //!< True if a device wants to create the TX queues by itself +}; + +} // namespace ns3 + +#endif /* NET_DEVICE_QUEUE_INTERFACE_H */ diff --git a/src/network/utils/queue-item.cc b/src/network/utils/queue-item.cc new file mode 100644 index 000000000..259bbc58c --- /dev/null +++ b/src/network/utils/queue-item.cc @@ -0,0 +1,128 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2016 Universita' degli Studi di Napoli Federico II + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Stefano Avallone + */ + +#include "queue-item.h" +#include "ns3/packet.h" +#include "ns3/log.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("QueueItem"); + +QueueItem::QueueItem (Ptr p) +{ + NS_LOG_FUNCTION (this << p); + m_packet = p; +} + +QueueItem::~QueueItem () +{ + NS_LOG_FUNCTION (this); + m_packet = 0; +} + +Ptr +QueueItem::GetPacket (void) const +{ + NS_LOG_FUNCTION (this); + return m_packet; +} + +uint32_t +QueueItem::GetSize (void) const +{ + NS_LOG_FUNCTION (this); + NS_ASSERT (m_packet != 0); + return m_packet->GetSize (); +} + +bool +QueueItem::GetUint8Value (QueueItem::Uint8Values field, uint8_t& value) const +{ + NS_LOG_FUNCTION (this); + return false; +} + +void +QueueItem::Print (std::ostream& os) const +{ + os << GetPacket(); +} + +std::ostream & operator << (std::ostream &os, const QueueItem &item) +{ + item.Print (os); + return os; +} + + +QueueDiscItem::QueueDiscItem (Ptr p, const Address& addr, uint16_t protocol) + : QueueItem (p), + m_address (addr), + m_protocol (protocol), + m_txq (0) +{ + NS_LOG_FUNCTION (this << p << addr << protocol); +} + +QueueDiscItem::~QueueDiscItem() +{ + NS_LOG_FUNCTION (this); +} + +Address +QueueDiscItem::GetAddress (void) const +{ + NS_LOG_FUNCTION (this); + return m_address; +} + +uint16_t +QueueDiscItem::GetProtocol (void) const +{ + NS_LOG_FUNCTION (this); + return m_protocol; +} + +uint8_t +QueueDiscItem::GetTxQueueIndex (void) const +{ + NS_LOG_FUNCTION (this); + return m_txq; +} + +void +QueueDiscItem::SetTxQueueIndex (uint8_t txq) +{ + NS_LOG_FUNCTION (this << (uint16_t) txq); + m_txq = txq; +} + +void +QueueDiscItem::Print (std::ostream& os) const +{ + os << GetPacket () << " " + << "Dst addr " << m_address << " " + << "proto " << (uint16_t) m_protocol << " " + << "txq " << (uint8_t) m_txq + ; +} + +} // namespace ns3 diff --git a/src/network/utils/queue-item.h b/src/network/utils/queue-item.h new file mode 100644 index 000000000..3d267d89a --- /dev/null +++ b/src/network/utils/queue-item.h @@ -0,0 +1,233 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2016 Universita' degli Studi di Napoli Federico II + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Stefano Avallone + */ +#ifndef QUEUE_ITEM_H +#define QUEUE_ITEM_H + +#include "ns3/ptr.h" +#include "ns3/simple-ref-count.h" +#include + +namespace ns3 { + +class Packet; + +/** + * \ingroup network + * \defgroup netdevice Network Device + */ + +/** + * \ingroup netdevice + * \brief Base class to represent items of packet Queues + * + * An item stored in an ns-3 packet Queue contains a packet and possibly other + * information. An item of the base class only contains a packet. Subclasses + * can be derived from this base class to allow items to contain additional + * information. + */ +class QueueItem : public SimpleRefCount +{ +public: + /** + * \brief Create a queue item containing a packet. + * \param p the packet included in the created item. + */ + QueueItem (Ptr p); + + virtual ~QueueItem (); + + /** + * \return the packet included in this item. + */ + Ptr GetPacket (void) const; + + /** + * \brief Use this method (instead of GetPacket ()->GetSize ()) to get the packet size + * + * Subclasses may keep header and payload separate to allow manipulating the header, + * so using this method ensures that the correct packet size is returned. + * + * \return the size of the packet included in this item. + */ + virtual uint32_t GetSize (void) const; + + /** + * \enum Uint8Values + * \brief 1-byte fields of the packet whose value can be retrieved, if present + */ + enum Uint8Values + { + IP_DSFIELD + }; + + /** + * \brief Retrieve the value of a given field from the packet, if present + * \param field the field whose value has to be retrieved + * \param value the output parameter to store the retrieved value + * + * \return true if the requested field is present in the packet, false otherwise. + */ + virtual bool GetUint8Value (Uint8Values field, uint8_t &value) const; + + /** + * \brief Print the item contents. + * \param os output stream in which the data should be printed. + */ + virtual void Print (std::ostream &os) const; + + /** + * TracedCallback signature for Ptr + * + * \param [in] item The queue item. + */ + typedef void (* TracedCallback) (Ptr item); + +private: + /** + * \brief Default constructor + * + * Defined and unimplemented to avoid misuse + */ + QueueItem (); + /** + * \brief Copy constructor + * + * Defined and unimplemented to avoid misuse + */ + QueueItem (const QueueItem &); + /** + * \brief Assignment operator + * + * Defined and unimplemented to avoid misuse + * \returns + */ + QueueItem &operator = (const QueueItem &); + + /** + * The packet contained in the queue item. + */ + Ptr m_packet; +}; + +/** + * \brief Stream insertion operator. + * + * \param os the stream + * \param item the item + * \returns a reference to the stream + */ +std::ostream& operator<< (std::ostream& os, const QueueItem &item); + + +/** + * \ingroup network + * + * QueueDiscItem is the abstract base class for items that are stored in a queue + * disc. It is derived from QueueItem (which only consists of a Ptr) + * to additionally store the destination MAC address, the + * L3 protocol number and the transmission queue index, + */ +class QueueDiscItem : public QueueItem { +public: + /** + * \brief Create a queue disc item. + * \param p the packet included in the created item. + * \param addr the destination MAC address + * \param protocol the L3 protocol number + */ + QueueDiscItem (Ptr p, const Address & addr, uint16_t protocol); + + virtual ~QueueDiscItem (); + + /** + * \brief Get the MAC address included in this item + * \return the MAC address included in this item. + */ + Address GetAddress (void) const; + + /** + * \brief Get the L3 protocol included in this item + * \return the L3 protocol included in this item. + */ + uint16_t GetProtocol (void) const; + + /** + * \brief Get the transmission queue index included in this item + * \return the transmission queue index included in this item. + */ + uint8_t GetTxQueueIndex (void) const; + + /** + * \brief Set the transmission queue index to store in this item + * \param txq the transmission queue index to store in this item. + */ + void SetTxQueueIndex (uint8_t txq); + + /** + * \brief Add the header to the packet + * + * Subclasses may keep header and payload separate to allow manipulating the header, + * so this method allows to add the header to the packet before sending the packet + * to the device. + */ + virtual void AddHeader (void) = 0; + + /** + * \brief Print the item contents. + * \param os output stream in which the data should be printed. + */ + virtual void Print (std::ostream &os) const; + + /** + * \brief Marks the packet as a substitute for dropping it, such as for Explicit Congestion Notification + * + * \return true if the packet gets marked, false otherwise + */ + virtual bool Mark (void) = 0; + +private: + /** + * \brief Default constructor + * + * Defined and unimplemented to avoid misuse + */ + QueueDiscItem (); + /** + * \brief Copy constructor + * + * Defined and unimplemented to avoid misuse + */ + QueueDiscItem (const QueueDiscItem &); + /** + * \brief Assignment operator + * + * Defined and unimplemented to avoid misuse + * \returns + */ + QueueDiscItem &operator = (const QueueDiscItem &); + + Address m_address; //!< MAC destination address + uint16_t m_protocol; //!< L3 Protocol number + uint8_t m_txq; //!< Transmission queue index +}; + +} // namespace ns3 + +#endif /* QUEUE_ITEM_H */ diff --git a/src/network/utils/queue.cc b/src/network/utils/queue.cc index 228fef2ff..b5d7f226b 100644 --- a/src/network/utils/queue.cc +++ b/src/network/utils/queue.cc @@ -16,7 +16,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "ns3/log.h" #include "ns3/abort.h" #include "ns3/enum.h" #include "ns3/uinteger.h" @@ -27,206 +26,78 @@ namespace ns3 { NS_LOG_COMPONENT_DEFINE ("Queue"); -NS_OBJECT_ENSURE_REGISTERED (Queue); +NS_OBJECT_ENSURE_REGISTERED (QueueBase); +NS_OBJECT_TEMPLATE_CLASS_DEFINE (Queue,Packet); -TypeId -Queue::GetTypeId (void) +TypeId +QueueBase::GetTypeId (void) { - static TypeId tid = TypeId ("ns3::Queue") + static TypeId tid = TypeId ("ns3::QueueBase") .SetParent () .SetGroupName ("Network") .AddAttribute ("Mode", "Whether to use bytes (see MaxBytes) or packets (see MaxPackets) as the maximum queue size metric.", EnumValue (QUEUE_MODE_PACKETS), - MakeEnumAccessor (&Queue::SetMode, - &Queue::GetMode), + MakeEnumAccessor (&QueueBase::SetMode, + &QueueBase::GetMode), MakeEnumChecker (QUEUE_MODE_BYTES, "QUEUE_MODE_BYTES", QUEUE_MODE_PACKETS, "QUEUE_MODE_PACKETS")) .AddAttribute ("MaxPackets", "The maximum number of packets accepted by this queue.", UintegerValue (100), - MakeUintegerAccessor (&Queue::SetMaxPackets, - &Queue::GetMaxPackets), + MakeUintegerAccessor (&QueueBase::SetMaxPackets, + &QueueBase::GetMaxPackets), MakeUintegerChecker ()) .AddAttribute ("MaxBytes", "The maximum number of bytes accepted by this queue.", UintegerValue (100 * 65535), - MakeUintegerAccessor (&Queue::SetMaxBytes, - &Queue::GetMaxBytes), + MakeUintegerAccessor (&QueueBase::SetMaxBytes, + &QueueBase::GetMaxBytes), MakeUintegerChecker ()) - .AddTraceSource ("Enqueue", "Enqueue a packet in the queue.", - MakeTraceSourceAccessor (&Queue::m_traceEnqueue), - "ns3::Packet::TracedCallback") - .AddTraceSource ("Dequeue", "Dequeue a packet from the queue.", - MakeTraceSourceAccessor (&Queue::m_traceDequeue), - "ns3::Packet::TracedCallback") - .AddTraceSource ("Drop", "Drop a packet (for whatever reason).", - MakeTraceSourceAccessor (&Queue::m_traceDrop), - "ns3::Packet::TracedCallback") .AddTraceSource ("PacketsInQueue", "Number of packets currently stored in the queue", - MakeTraceSourceAccessor (&Queue::m_nPackets), + MakeTraceSourceAccessor (&QueueBase::m_nPackets), "ns3::TracedValueCallback::Uint32") .AddTraceSource ("BytesInQueue", "Number of bytes currently stored in the queue", - MakeTraceSourceAccessor (&Queue::m_nBytes), + MakeTraceSourceAccessor (&QueueBase::m_nBytes), "ns3::TracedValueCallback::Uint32") ; return tid; } -Queue::Queue() : +QueueBase::QueueBase () : m_nBytes (0), m_nTotalReceivedBytes (0), m_nPackets (0), m_nTotalReceivedPackets (0), m_nTotalDroppedBytes (0), + m_nTotalDroppedBytesBeforeEnqueue (0), + m_nTotalDroppedBytesAfterDequeue (0), m_nTotalDroppedPackets (0), + m_nTotalDroppedPacketsBeforeEnqueue (0), + m_nTotalDroppedPacketsAfterDequeue (0), m_mode (QUEUE_MODE_PACKETS) { NS_LOG_FUNCTION (this); } -Queue::~Queue() +QueueBase::~QueueBase () { NS_LOG_FUNCTION (this); } - -bool -Queue::Enqueue (Ptr item) -{ - NS_LOG_FUNCTION (this << item); - - if (m_mode == QUEUE_MODE_PACKETS && (m_nPackets.Get () >= m_maxPackets)) - { - NS_LOG_LOGIC ("Queue full (at max packets) -- dropping pkt"); - Drop (item); - return false; - } - - if (m_mode == QUEUE_MODE_BYTES && (m_nBytes.Get () + item->GetPacketSize () > m_maxBytes)) - { - NS_LOG_LOGIC ("Queue full (packet would exceed max bytes) -- dropping pkt"); - Drop (item); - return false; - } - - // - // If DoEnqueue fails, Queue::Drop is called by the subclass - // - bool retval = DoEnqueue (item); - if (retval) - { - NS_LOG_LOGIC ("m_traceEnqueue (p)"); - m_traceEnqueue (item->GetPacket ()); - - uint32_t size = item->GetPacketSize (); - m_nBytes += size; - m_nTotalReceivedBytes += size; - - m_nPackets++; - m_nTotalReceivedPackets++; - } - return retval; -} - -Ptr -Queue::Dequeue (void) -{ - NS_LOG_FUNCTION (this); - - if (m_nPackets.Get () == 0) - { - NS_LOG_LOGIC ("Queue empty"); - return 0; - } - - Ptr item = DoDequeue (); - - if (item != 0) - { - NS_ASSERT (m_nBytes.Get () >= item->GetPacketSize ()); - NS_ASSERT (m_nPackets.Get () > 0); - - m_nBytes -= item->GetPacketSize (); - m_nPackets--; - - NS_LOG_LOGIC ("m_traceDequeue (packet)"); - m_traceDequeue (item->GetPacket ()); - } - return item; -} - -Ptr -Queue::Remove (void) -{ - NS_LOG_FUNCTION (this); - - if (m_nPackets.Get () == 0) - { - NS_LOG_LOGIC ("Queue empty"); - return 0; - } - - Ptr item = DoRemove (); - - if (item != 0) - { - NS_ASSERT (m_nBytes.Get () >= item->GetPacketSize ()); - NS_ASSERT (m_nPackets.Get () > 0); - - m_nBytes -= item->GetPacketSize (); - m_nPackets--; - - Drop (item); - } - return item; -} - void -Queue::DequeueAll (void) +QueueBase::AppendItemTypeIfNotPresent (std::string& typeId, const std::string& itemType) { - NS_LOG_FUNCTION (this); - while (!IsEmpty ()) + if (typeId.back () != '>') { - Dequeue (); + typeId.append ("<" + itemType + ">"); } } -Ptr -Queue::Peek (void) const -{ - NS_LOG_FUNCTION (this); - - if (m_nPackets.Get () == 0) - { - NS_LOG_LOGIC ("Queue empty"); - return 0; - } - - return DoPeek (); -} - - -uint32_t -Queue::GetNPackets (void) const -{ - NS_LOG_FUNCTION (this); - NS_LOG_LOGIC ("returns " << m_nPackets); - return m_nPackets; -} - -uint32_t -Queue::GetNBytes (void) const -{ - NS_LOG_FUNCTION (this); - NS_LOG_LOGIC (" returns " << m_nBytes); - return m_nBytes; -} - bool -Queue::IsEmpty (void) const +QueueBase::IsEmpty (void) const { NS_LOG_FUNCTION (this); NS_LOG_LOGIC ("returns " << (m_nPackets.Get () == 0)); @@ -234,7 +105,23 @@ Queue::IsEmpty (void) const } uint32_t -Queue::GetTotalReceivedBytes (void) const +QueueBase::GetNPackets (void) const +{ + NS_LOG_FUNCTION (this); + NS_LOG_LOGIC ("returns " << m_nPackets); + return m_nPackets; +} + +uint32_t +QueueBase::GetNBytes (void) const +{ + NS_LOG_FUNCTION (this); + NS_LOG_LOGIC (" returns " << m_nBytes); + return m_nBytes; +} + +uint32_t +QueueBase::GetTotalReceivedBytes (void) const { NS_LOG_FUNCTION (this); NS_LOG_LOGIC ("returns " << m_nTotalReceivedBytes); @@ -242,7 +129,7 @@ Queue::GetTotalReceivedBytes (void) const } uint32_t -Queue::GetTotalReceivedPackets (void) const +QueueBase::GetTotalReceivedPackets (void) const { NS_LOG_FUNCTION (this); NS_LOG_LOGIC ("returns " << m_nTotalReceivedPackets); @@ -250,7 +137,7 @@ Queue::GetTotalReceivedPackets (void) const } uint32_t -Queue:: GetTotalDroppedBytes (void) const +QueueBase:: GetTotalDroppedBytes (void) const { NS_LOG_FUNCTION (this); NS_LOG_LOGIC ("returns " << m_nTotalDroppedBytes); @@ -258,25 +145,61 @@ Queue:: GetTotalDroppedBytes (void) const } uint32_t -Queue::GetTotalDroppedPackets (void) const +QueueBase:: GetTotalDroppedBytesBeforeEnqueue (void) const +{ + NS_LOG_FUNCTION (this); + NS_LOG_LOGIC ("returns " << m_nTotalDroppedBytesBeforeEnqueue); + return m_nTotalDroppedBytesBeforeEnqueue; +} + +uint32_t +QueueBase:: GetTotalDroppedBytesAfterDequeue (void) const +{ + NS_LOG_FUNCTION (this); + NS_LOG_LOGIC ("returns " << m_nTotalDroppedBytesAfterDequeue); + return m_nTotalDroppedBytesAfterDequeue; +} + +uint32_t +QueueBase::GetTotalDroppedPackets (void) const { NS_LOG_FUNCTION (this); NS_LOG_LOGIC ("returns " << m_nTotalDroppedPackets); return m_nTotalDroppedPackets; } -void -Queue::ResetStatistics (void) +uint32_t +QueueBase::GetTotalDroppedPacketsBeforeEnqueue (void) const +{ + NS_LOG_FUNCTION (this); + NS_LOG_LOGIC ("returns " << m_nTotalDroppedPacketsBeforeEnqueue); + return m_nTotalDroppedPacketsBeforeEnqueue; +} + +uint32_t +QueueBase::GetTotalDroppedPacketsAfterDequeue (void) const +{ + NS_LOG_FUNCTION (this); + NS_LOG_LOGIC ("returns " << m_nTotalDroppedPacketsAfterDequeue); + return m_nTotalDroppedPacketsAfterDequeue; +} + +void +QueueBase::ResetStatistics (void) { NS_LOG_FUNCTION (this); m_nTotalReceivedBytes = 0; m_nTotalReceivedPackets = 0; m_nTotalDroppedBytes = 0; + m_nTotalDroppedBytesBeforeEnqueue = 0; + m_nTotalDroppedBytesAfterDequeue = 0; m_nTotalDroppedPackets = 0; + m_nTotalDroppedPacketsBeforeEnqueue = 0; + m_nTotalDroppedPacketsAfterDequeue = 0; } void -Queue::SetMode (Queue::QueueMode mode) +QueueBase::SetMode (QueueBase::QueueMode mode) { NS_LOG_FUNCTION (this << mode); @@ -294,15 +217,15 @@ Queue::SetMode (Queue::QueueMode mode) m_mode = mode; } -Queue::QueueMode -Queue::GetMode (void) const +QueueBase::QueueMode +QueueBase::GetMode (void) const { NS_LOG_FUNCTION (this); return m_mode; } void -Queue::SetMaxPackets (uint32_t maxPackets) +QueueBase::SetMaxPackets (uint32_t maxPackets) { NS_LOG_FUNCTION (this << maxPackets); @@ -316,14 +239,14 @@ Queue::SetMaxPackets (uint32_t maxPackets) } uint32_t -Queue::GetMaxPackets (void) const +QueueBase::GetMaxPackets (void) const { NS_LOG_FUNCTION (this); return m_maxPackets; } void -Queue::SetMaxBytes (uint32_t maxBytes) +QueueBase::SetMaxBytes (uint32_t maxBytes) { NS_LOG_FUNCTION (this << maxBytes); @@ -337,40 +260,16 @@ Queue::SetMaxBytes (uint32_t maxBytes) } uint32_t -Queue::GetMaxBytes (void) const +QueueBase::GetMaxBytes (void) const { NS_LOG_FUNCTION (this); return m_maxBytes; } void -Queue::SetDropCallback (DropCallback cb) +QueueBase::DoNsLog (const enum LogLevel level, std::string str) const { - m_dropCallback = cb; -} - -void -Queue::NotifyDrop (Ptr item) -{ - NS_LOG_FUNCTION (this << item); - - if (!m_dropCallback.IsNull ()) - { - m_dropCallback (item); - } -} - -void -Queue::Drop (Ptr item) -{ - NS_LOG_FUNCTION (this << item); - - m_nTotalDroppedPackets++; - m_nTotalDroppedBytes += item->GetPacketSize (); - - NS_LOG_LOGIC ("m_traceDrop (p)"); - m_traceDrop (item->GetPacket ()); - NotifyDrop (item); + NS_LOG (level, str); } } // namespace ns3 diff --git a/src/network/utils/queue.h b/src/network/utils/queue.h index 93f28592d..e809a02cd 100644 --- a/src/network/utils/queue.h +++ b/src/network/utils/queue.h @@ -26,8 +26,11 @@ #include "ns3/packet.h" #include "ns3/object.h" #include "ns3/traced-callback.h" -#include "ns3/net-device.h" #include "ns3/traced-value.h" +#include "ns3/unused.h" +#include "ns3/log.h" +#include +#include namespace ns3 { @@ -35,13 +38,15 @@ namespace ns3 { * \ingroup network * \defgroup queue Queue */ + /** * \ingroup queue * \brief Abstract base class for packet Queues - * - * This class defines the base APIs for packet queues in the ns-3 system + * + * This class defines the subset of the base APIs for packet queues in the ns-3 system + * that is independent of the type of enqueued objects */ -class Queue : public Object +class QueueBase : public Object { public: /** @@ -50,43 +55,40 @@ public: */ static TypeId GetTypeId (void); - Queue (); - virtual ~Queue (); + QueueBase (); + virtual ~QueueBase (); + + /** + * \brief Append the item type to the provided type ID if the latter does not + * end with '>' + * + * \param typeId the type ID + * \param itemType the item type + * + * This method is meant to be invoked by helpers to save users from + * specifying the type of items stored in a queue. For instance, + * PointToPointHelper::SetQueue calls + * + * \code + * QueueBase::AppendItemTypeIfNotPresent (type, "Packet"); + * \endcode + * + * where type specifies the queue type (e.g., "ns3::DropTailQueue"). + * This allows users to call SetQueue ("ns3::DropTailQueue") + * instead of SetQueue ("ns3::DropTailQueue") + */ + static void AppendItemTypeIfNotPresent (std::string& typeId, const std::string& itemType); /** * \return true if the queue is empty; false otherwise */ bool IsEmpty (void) const; - /** - * Place a queue item into the rear of the Queue - * \param item item to enqueue - * \return True if the operation was successful; false otherwise - */ - bool Enqueue (Ptr item); - /** - * Remove an item from the front of the Queue, counting it as dequeued - * \return 0 if the operation was not successful; the item otherwise. - */ - Ptr Dequeue (void); - /** - * Remove an item from the front of the Queue, counting it as dropped - * \return 0 if the operation was not successful; the item otherwise. - */ - Ptr Remove (void); - /** - * Get a copy of the item at the front of the queue without removing it - * \return 0 if the operation was not successful; the item otherwise. - */ - Ptr Peek (void) const; - /** - * Flush the queue. - */ - void DequeueAll (void); /** * \return The number of packets currently stored in the Queue */ uint32_t GetNPackets (void) const; + /** * \return The number of bytes currently occupied by the packets in the Queue */ @@ -94,29 +96,60 @@ public: /** * \return The total number of bytes received by this Queue since the - * simulation began, or since ResetStatistics was called, according to + * simulation began, or since ResetStatistics was called, according to * whichever happened more recently - * */ uint32_t GetTotalReceivedBytes (void) const; + /** * \return The total number of packets received by this Queue since the - * simulation began, or since ResetStatistics was called, according to + * simulation began, or since ResetStatistics was called, according to * whichever happened more recently */ uint32_t GetTotalReceivedPackets (void) const; + /** * \return The total number of bytes dropped by this Queue since the - * simulation began, or since ResetStatistics was called, according to + * simulation began, or since ResetStatistics was called, according to * whichever happened more recently */ uint32_t GetTotalDroppedBytes (void) const; + /** - * \return The total number of bytes dropped by this Queue since the - * simulation began, or since ResetStatistics was called, according to + * \return The total number of bytes dropped before enqueue by this Queue + * since the simulation began, or since ResetStatistics was called, according + * to whichever happened more recently + */ + uint32_t GetTotalDroppedBytesBeforeEnqueue (void) const; + + /** + * \return The total number of bytes dropped after dequeue by this Queue + * since the simulation began, or since ResetStatistics was called, according + * to whichever happened more recently + */ + uint32_t GetTotalDroppedBytesAfterDequeue (void) const; + + /** + * \return The total number of packets dropped by this Queue since the + * simulation began, or since ResetStatistics was called, according to * whichever happened more recently */ uint32_t GetTotalDroppedPackets (void) const; + + /** + * \return The total number of packets dropped before enqueue by this Queue + * since the simulation began, or since ResetStatistics was called, according + * to whichever happened more recently + */ + uint32_t GetTotalDroppedPacketsBeforeEnqueue (void) const; + + /** + * \return The total number of packets dropped after dequeue by this Queue + * since the simulation began, or since ResetStatistics was called, according + * to whichever happened more recently + */ + uint32_t GetTotalDroppedPacketsAfterDequeue (void) const; + /** * Resets the counts for dropped packets, dropped bytes, received packets, and * received bytes. @@ -138,14 +171,14 @@ public: * * \param mode The operating mode of this device. */ - void SetMode (Queue::QueueMode mode); + void SetMode (QueueBase::QueueMode mode); /** - * Get the encapsulation mode of this device. + * Get the operating mode of this device. * - * \returns The encapsulation mode of this device. + * \returns The operating mode of this device. */ - Queue::QueueMode GetMode (void) const; + QueueBase::QueueMode GetMode (void) const; /** * \brief Set the maximum amount of packets that can be stored in this queue @@ -195,28 +228,122 @@ public: double GetDroppedPacketsPerSecondVariance (void); #endif - /// Callback set by the object (e.g., a queue disc) that wants to be notified of a packet drop - typedef Callback > DropCallback; +protected: + /** + * \brief Actually pass messages to the ns-3 logging system + * + * \param level the log level + * \param str the message to log + */ + void DoNsLog (const enum LogLevel level, std::string str) const; + +private: + TracedValue m_nBytes; //!< Number of bytes in the queue + uint32_t m_nTotalReceivedBytes; //!< Total received bytes + TracedValue m_nPackets; //!< Number of packets in the queue + uint32_t m_nTotalReceivedPackets; //!< Total received packets + uint32_t m_nTotalDroppedBytes; //!< Total dropped bytes + uint32_t m_nTotalDroppedBytesBeforeEnqueue; //!< Total dropped bytes before enqueue + uint32_t m_nTotalDroppedBytesAfterDequeue; //!< Total dropped bytes after dequeue + uint32_t m_nTotalDroppedPackets; //!< Total dropped packets + uint32_t m_nTotalDroppedPacketsBeforeEnqueue; //!< Total dropped packets before enqueue + uint32_t m_nTotalDroppedPacketsAfterDequeue; //!< Total dropped packets after dequeue + + uint32_t m_maxPackets; //!< max packets in the queue + uint32_t m_maxBytes; //!< max bytes in the queue + QueueMode m_mode; //!< queue mode (packets or bytes) + + template + friend class Queue; +}; + + +/** + * \ingroup queue + * \brief Template class for packet Queues + * + * This class defines the subset of the base APIs for packet queues in the ns-3 system + * that is dependent on the type of enqueued objects. + * + * Queue is a template class. The type of the objects stored within the queue + * is specified by the type parameter, which can be any class providing a + * GetSize () method (e.g., Packet, QueueDiscItem, etc.). Subclasses need to + * implement the DoEnqueue, DoDequeue, DoRemove and DoPeek methods. + * + * Users of the Queue template class usually hold a queue through a smart pointer, + * hence forward declaration is recommended to avoid pulling the implementation + * of the templates included in this file. Thus, do not include queue.h but add + * the following forward declaration in your .h file: + * + * \code + * template class Queue; + * \endcode + * + * Then, include queue.h in the corresponding .cc file. + */ +template +class Queue : public QueueBase +{ +public: + /** + * \brief Get the type ID. + * \return the object TypeId + */ + static TypeId GetTypeId (void); + + Queue (); + virtual ~Queue (); /** - * \brief Set the drop callback - * \param cb the callback to set - * - * Called when a queue is added to a queue disc in order to set a - * callback to the Drop method of the queue disc. + * Place a queue item into the rear of the Queue + * \param item item to enqueue + * \return True if the operation was successful; false otherwise */ - virtual void SetDropCallback (DropCallback cb); + bool Enqueue (Ptr item); + + /** + * Remove an item from the front of the Queue, counting it as dequeued + * \return 0 if the operation was not successful; the item otherwise. + */ + Ptr Dequeue (void); + + /** + * Remove an item from the front of the Queue, counting it as dropped + * \return 0 if the operation was not successful; the item otherwise. + */ + Ptr Remove (void); + + /** + * Get a copy of the item at the front of the queue without removing it + * \return 0 if the operation was not successful; the item otherwise. + */ + Ptr Peek (void) const; + + /** + * Flush the queue. + */ + void Flush (void); protected: /** - * \brief Drop a packet + * \brief Drop a packet before enqueue * \param item item that was dropped * * This method is called by the base class when a packet is dropped because * the queue is full and by the subclasses to notify parent (this class) that - * a packet has been dropped for other reasons. + * a packet has been dropped for other reasons before being enqueued. */ - void Drop (Ptr item); + void DropBeforeEnqueue (Ptr item); + + /** + * \brief Drop a packet after dequeue + * \param item item that was dropped + * + * This method is called by the base class when a Remove operation is requested + * and by the subclasses to notify parent (this class) that a packet has been + * dropped for other reasons after being dequeued. + */ + void DropAfterDequeue (Ptr item); private: /** @@ -224,49 +351,241 @@ private: * \param item the item to enqueue * \return true if success, false if the packet has been dropped. */ - virtual bool DoEnqueue (Ptr item) = 0; + virtual bool DoEnqueue (Ptr item) = 0; + /** * Pull the item to dequeue from the queue * \return the item. */ - virtual Ptr DoDequeue (void) = 0; + virtual Ptr DoDequeue (void) = 0; + /** * Pull the item to drop from the queue * \return the item. */ - virtual Ptr DoRemove (void) = 0; + virtual Ptr DoRemove (void) = 0; + /** * Peek the front item in the queue * \return the item. */ - virtual Ptr DoPeek (void) const = 0; - - /** - * \brief Notification of a packet drop - * \param item item that was dropped - */ - void NotifyDrop (Ptr item); + virtual Ptr DoPeek (void) const = 0; +private: /// Traced callback: fired when a packet is enqueued - TracedCallback > m_traceEnqueue; + TracedCallback > m_traceEnqueue; /// Traced callback: fired when a packet is dequeued - TracedCallback > m_traceDequeue; + TracedCallback > m_traceDequeue; /// Traced callback: fired when a packet is dropped - TracedCallback > m_traceDrop; - - TracedValue m_nBytes; //!< Number of bytes in the queue - uint32_t m_nTotalReceivedBytes; //!< Total received bytes - TracedValue m_nPackets; //!< Number of packets in the queue - uint32_t m_nTotalReceivedPackets; //!< Total received packets - uint32_t m_nTotalDroppedBytes; //!< Total dropped bytes - uint32_t m_nTotalDroppedPackets; //!< Total dropped packets - - uint32_t m_maxPackets; //!< max packets in the queue - uint32_t m_maxBytes; //!< max bytes in the queue - QueueMode m_mode; //!< queue mode (packets or bytes limited) - DropCallback m_dropCallback; //!< drop callback + TracedCallback > m_traceDrop; + /// Traced callback: fired when a packet is dropped before enqueue + TracedCallback > m_traceDropBeforeEnqueue; + /// Traced callback: fired when a packet is dropped after dequeue + TracedCallback > m_traceDropAfterDequeue; }; + +#define QUEUE_LOG(level,params) \ + { \ + std::stringstream ss; \ + ss << params; \ + QueueBase::DoNsLog (level, ss.str ()); \ + } + + +/** + * Implementation of the templates declared above. + */ + +template +TypeId +Queue::GetTypeId (void) +{ + std::string name = GetTypeParamName > (); + static TypeId tid = TypeId (("ns3::Queue<" + name + ">").c_str ()) + .SetParent () + .SetGroupName ("Network") + .AddTraceSource ("Enqueue", "Enqueue a packet in the queue.", + MakeTraceSourceAccessor (&Queue::m_traceEnqueue), + "ns3::" + name + "::TracedCallback") + .AddTraceSource ("Dequeue", "Dequeue a packet from the queue.", + MakeTraceSourceAccessor (&Queue::m_traceDequeue), + "ns3::" + name + "::TracedCallback") + .AddTraceSource ("Drop", "Drop a packet (for whatever reason).", + MakeTraceSourceAccessor (&Queue::m_traceDrop), + "ns3::" + name + "::TracedCallback") + .AddTraceSource ("DropBeforeEnqueue", "Drop a packet before enqueue.", + MakeTraceSourceAccessor (&Queue::m_traceDropBeforeEnqueue), + "ns3::" + name + "::TracedCallback") + .AddTraceSource ("DropAfterDequeue", "Drop a packet after dequeue.", + MakeTraceSourceAccessor (&Queue::m_traceDropAfterDequeue), + "ns3::" + name + "::TracedCallback") + ; + return tid; +} + +template +Queue::Queue () +{ +} + +template +Queue::~Queue () +{ +} + +template +bool +Queue::Enqueue (Ptr item) +{ + QUEUE_LOG (LOG_LOGIC, "Queue:Enqueue(" << this << ", " << item << ")"); + + if (m_mode == QUEUE_MODE_PACKETS && (m_nPackets.Get () >= m_maxPackets)) + { + QUEUE_LOG (LOG_LOGIC, "Queue full (at max packets) -- dropping pkt"); + DropBeforeEnqueue (item); + return false; + } + + if (m_mode == QUEUE_MODE_BYTES && (m_nBytes.Get () + item->GetSize () > m_maxBytes)) + { + QUEUE_LOG (LOG_LOGIC, "Queue full (packet would exceed max bytes) -- dropping pkt"); + DropBeforeEnqueue (item); + return false; + } + + // + // If DoEnqueue fails, Queue::DropBeforeEnqueue is called by the subclass + // + bool retval = DoEnqueue (item); + if (retval) + { + uint32_t size = item->GetSize (); + m_nBytes += size; + m_nTotalReceivedBytes += size; + + m_nPackets++; + m_nTotalReceivedPackets++; + + QUEUE_LOG (LOG_LOGIC, "m_traceEnqueue (p)"); + m_traceEnqueue (item); + } + return retval; +} + +template +Ptr +Queue::Dequeue (void) +{ + QUEUE_LOG (LOG_LOGIC, "Queue:Dequeue(" << this << ")"); + + if (m_nPackets.Get () == 0) + { + QUEUE_LOG (LOG_LOGIC, "Queue empty"); + return 0; + } + + Ptr item = DoDequeue (); + + if (item != 0) + { + NS_ASSERT (m_nBytes.Get () >= item->GetSize ()); + NS_ASSERT (m_nPackets.Get () > 0); + + m_nBytes -= item->GetSize (); + m_nPackets--; + + QUEUE_LOG (LOG_LOGIC, "m_traceDequeue (p)"); + m_traceDequeue (item); + } + return item; +} + +template +Ptr +Queue::Remove (void) +{ + QUEUE_LOG (LOG_LOGIC, "Queue:Remove(" << this << ")"); + + if (m_nPackets.Get () == 0) + { + QUEUE_LOG (LOG_LOGIC, "Queue empty"); + return 0; + } + + Ptr item = DoRemove (); + + if (item != 0) + { + NS_ASSERT (m_nBytes.Get () >= item->GetSize ()); + NS_ASSERT (m_nPackets.Get () > 0); + + m_nBytes -= item->GetSize (); + m_nPackets--; + + DropAfterDequeue (item); + } + return item; +} + +template +void +Queue::Flush (void) +{ + QUEUE_LOG (LOG_LOGIC, "Queue:Flush(" << this << ")"); + while (!IsEmpty ()) + { + Remove (); + } +} + +template +Ptr +Queue::Peek (void) const +{ + QUEUE_LOG (LOG_LOGIC, "Queue:Peek(" << this << ")"); + + if (m_nPackets.Get () == 0) + { + QUEUE_LOG (LOG_LOGIC, "Queue empty"); + return 0; + } + + return DoPeek (); +} + +template +void +Queue::DropBeforeEnqueue (Ptr item) +{ + QUEUE_LOG (LOG_LOGIC, "Queue:DropBeforeEnqueue(" << this << ", " << item << ")"); + + m_nTotalDroppedPackets++; + m_nTotalDroppedPacketsBeforeEnqueue++; + m_nTotalDroppedBytes += item->GetSize (); + m_nTotalDroppedBytesBeforeEnqueue += item->GetSize (); + + QUEUE_LOG (LOG_LOGIC, "m_traceDropBeforeEnqueue (p)"); + m_traceDrop (item); + m_traceDropBeforeEnqueue (item); +} + +template +void +Queue::DropAfterDequeue (Ptr item) +{ + QUEUE_LOG (LOG_LOGIC, "Queue:DropAfterDequeue(" << this << ", " << item << ")"); + + m_nTotalDroppedPackets++; + m_nTotalDroppedPacketsAfterDequeue++; + m_nTotalDroppedBytes += item->GetSize (); + m_nTotalDroppedBytesAfterDequeue += item->GetSize (); + + QUEUE_LOG (LOG_LOGIC, "m_traceDropAfterDequeue (p)"); + m_traceDrop (item); + m_traceDropAfterDequeue (item); +} + } // namespace ns3 #endif /* QUEUE_H */ diff --git a/src/network/utils/simple-net-device.cc b/src/network/utils/simple-net-device.cc index e227efda8..412620a1f 100644 --- a/src/network/utils/simple-net-device.cc +++ b/src/network/utils/simple-net-device.cc @@ -29,7 +29,7 @@ #include "ns3/string.h" #include "ns3/tag.h" #include "ns3/simulator.h" -#include "ns3/drop-tail-queue.h" +#include "ns3/queue.h" namespace ns3 { @@ -202,9 +202,9 @@ SimpleNetDevice::GetTypeId (void) MakeBooleanChecker ()) .AddAttribute ("TxQueue", "A queue to use as the transmit queue in the device.", - StringValue ("ns3::DropTailQueue"), + StringValue ("ns3::DropTailQueue"), MakePointerAccessor (&SimpleNetDevice::m_queue), - MakePointerChecker ()) + MakePointerChecker > ()) .AddAttribute ("DataRate", "The default data rate for point to point links. Zero means infinite", DataRateValue (DataRate ("0b/s")), @@ -280,7 +280,7 @@ SimpleNetDevice::SetChannel (Ptr channel) m_linkChangeCallbacks (); } -Ptr +Ptr > SimpleNetDevice::GetQueue () const { NS_LOG_FUNCTION (this); @@ -288,7 +288,7 @@ SimpleNetDevice::GetQueue () const } void -SimpleNetDevice::SetQueue (Ptr q) +SimpleNetDevice::SetQueue (Ptr > q) { NS_LOG_FUNCTION (this << q); m_queue = q; @@ -444,11 +444,11 @@ SimpleNetDevice::SendFrom (Ptr p, const Address& source, const Address& p->AddPacketTag (tag); - if (m_queue->Enqueue (Create (p))) + if (m_queue->Enqueue (p)) { if (m_queue->GetNPackets () == 1 && !TransmitCompleteEvent.IsRunning ()) { - p = m_queue->Dequeue ()->GetPacket (); + p = m_queue->Dequeue (); p->RemovePacketTag (tag); Time txTime = Time (0); if (m_bps > DataRate (0)) @@ -477,7 +477,7 @@ SimpleNetDevice::TransmitComplete () return; } - Ptr packet = m_queue->Dequeue ()->GetPacket (); + Ptr packet = m_queue->Dequeue (); SimpleTag tag; packet->RemovePacketTag (tag); @@ -537,7 +537,7 @@ SimpleNetDevice::DoDispose (void) m_channel = 0; m_node = 0; m_receiveErrorModel = 0; - m_queue->DequeueAll (); + m_queue->Flush (); if (TransmitCompleteEvent.IsRunning ()) { TransmitCompleteEvent.Cancel (); diff --git a/src/network/utils/simple-net-device.h b/src/network/utils/simple-net-device.h index c9635e6d1..c4f0bef6d 100644 --- a/src/network/utils/simple-net-device.h +++ b/src/network/utils/simple-net-device.h @@ -25,7 +25,6 @@ #include "ns3/traced-callback.h" #include "ns3/net-device.h" -#include "ns3/queue.h" #include "ns3/data-rate.h" #include "ns3/event-id.h" @@ -33,6 +32,7 @@ namespace ns3 { +template class Queue; class SimpleChannel; class Node; class ErrorModel; @@ -87,14 +87,14 @@ public: * * \param queue Ptr to the new queue. */ - void SetQueue (Ptr queue); + void SetQueue (Ptr > queue); /** * Get a copy of the attached Queue. * * \returns Ptr to the queue. */ - Ptr GetQueue (void) const; + Ptr > GetQueue (void) const; /** * Attach a receive ErrorModel to the SimpleNetDevice. @@ -171,7 +171,7 @@ private: */ bool m_pointToPointMode; - Ptr m_queue; //!< The Queue for outgoing packets. + Ptr > m_queue; //!< The Queue for outgoing packets. DataRate m_bps; //!< The device nominal Data rate. Zero means infinite EventId TransmitCompleteEvent; //!< the Tx Complete event diff --git a/src/network/wscript b/src/network/wscript index c7776959b..fc702af5d 100644 --- a/src/network/wscript +++ b/src/network/wscript @@ -51,7 +51,9 @@ def build(bld): 'utils/pcap-file.cc', 'utils/pcap-file-wrapper.cc', 'utils/queue.cc', + 'utils/queue-item.cc', 'utils/queue-limits.cc', + 'utils/net-device-queue-interface.cc', 'utils/radiotap-header.cc', 'utils/simple-channel.cc', 'utils/simple-net-device.cc', @@ -136,7 +138,9 @@ def build(bld): 'utils/pcap-file-wrapper.h', 'utils/generic-phy.h', 'utils/queue.h', + 'utils/queue-item.h', 'utils/queue-limits.h', + 'utils/net-device-queue-interface.h', 'utils/radiotap-header.h', 'utils/sequence-number.h', 'utils/sgi-hashmap.h', diff --git a/src/point-to-point/examples/main-attribute-value.cc b/src/point-to-point/examples/main-attribute-value.cc index eed1f9b83..43468f635 100644 --- a/src/point-to-point/examples/main-attribute-value.cc +++ b/src/point-to-point/examples/main-attribute-value.cc @@ -52,16 +52,16 @@ main (int argc, char *argv[]) // // Here, we set it to 80 packets. We could use one of two value types: // a string-based value or a UintegerValue value - Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("80")); + Config::SetDefault ("ns3::DropTailQueue::MaxPackets", StringValue ("80")); // The below function call is redundant - Config::SetDefault ("ns3::DropTailQueue::MaxPackets", UintegerValue (80)); + Config::SetDefault ("ns3::DropTailQueue::MaxPackets", UintegerValue (80)); // Allow the user to override any of the defaults and the above // SetDefaults() at run-time, via command-line arguments // For example, via "--ns3::DropTailQueue::MaxPackets=80" CommandLine cmd; // This provides yet another way to set the value from the command line: - cmd.AddValue ("maxPackets", "ns3::DropTailQueue::MaxPackets"); + cmd.AddValue ("maxPackets", "ns3::DropTailQueue::MaxPackets"); cmd.Parse (argc, argv); // Now, we will create a few objects using the low-level API @@ -70,7 +70,7 @@ main (int argc, char *argv[]) Ptr net0 = CreateObject (); n0->AddDevice (net0); - Ptr q = CreateObject (); + Ptr > q = CreateObject > (); net0->SetQueue (q); // At this point, we have created a single node (Node 0) and a @@ -93,11 +93,11 @@ main (int argc, char *argv[]) // TxQueue PointerValue ptr; net0->GetAttribute ("TxQueue", ptr); - Ptr txQueue = ptr.Get (); + Ptr > txQueue = ptr.Get > (); // Using the GetObject function, we can perform a safe downcast // to a DropTailQueue, where MaxPackets is a member - Ptr dtq = txQueue->GetObject (); + Ptr > dtq = txQueue->GetObject > (); NS_ASSERT (dtq); // Next, we can get the value of an attribute on this queue diff --git a/src/point-to-point/helper/point-to-point-helper.cc b/src/point-to-point/helper/point-to-point-helper.cc index 4b9b54263..68806e211 100644 --- a/src/point-to-point/helper/point-to-point-helper.cc +++ b/src/point-to-point/helper/point-to-point-helper.cc @@ -40,7 +40,7 @@ NS_LOG_COMPONENT_DEFINE ("PointToPointHelper"); PointToPointHelper::PointToPointHelper () { - m_queueFactory.SetTypeId ("ns3::DropTailQueue"); + m_queueFactory.SetTypeId ("ns3::DropTailQueue"); m_deviceFactory.SetTypeId ("ns3::PointToPointNetDevice"); m_channelFactory.SetTypeId ("ns3::PointToPointChannel"); m_remoteChannelFactory.SetTypeId ("ns3::PointToPointRemoteChannel"); @@ -53,6 +53,8 @@ PointToPointHelper::SetQueue (std::string type, std::string n3, const AttributeValue &v3, std::string n4, const AttributeValue &v4) { + QueueBase::AppendItemTypeIfNotPresent (type, "Packet"); + m_queueFactory.SetTypeId (type); m_queueFactory.Set (n1, v1); m_queueFactory.Set (n2, v2); @@ -167,10 +169,10 @@ PointToPointHelper::EnableAsciiInternal ( // The "+", '-', and 'd' events are driven by trace sources actually in the // transmit queue. // - Ptr queue = device->GetQueue (); - asciiTraceHelper.HookDefaultEnqueueSinkWithoutContext (queue, "Enqueue", theStream); - asciiTraceHelper.HookDefaultDropSinkWithoutContext (queue, "Drop", theStream); - asciiTraceHelper.HookDefaultDequeueSinkWithoutContext (queue, "Dequeue", theStream); + Ptr > queue = device->GetQueue (); + asciiTraceHelper.HookDefaultEnqueueSinkWithoutContext > (queue, "Enqueue", theStream); + asciiTraceHelper.HookDefaultDropSinkWithoutContext > (queue, "Drop", theStream); + asciiTraceHelper.HookDefaultDequeueSinkWithoutContext > (queue, "Dequeue", theStream); // PhyRxDrop trace source for "d" event asciiTraceHelper.HookDefaultDropSinkWithoutContext (device, "PhyRxDrop", theStream); @@ -229,12 +231,12 @@ PointToPointHelper::Install (Ptr a, Ptr b) Ptr devA = m_deviceFactory.Create (); devA->SetAddress (Mac48Address::Allocate ()); a->AddDevice (devA); - Ptr queueA = m_queueFactory.Create (); + Ptr > queueA = m_queueFactory.Create > (); devA->SetQueue (queueA); Ptr devB = m_deviceFactory.Create (); devB->SetAddress (Mac48Address::Allocate ()); b->AddDevice (devB); - Ptr queueB = m_queueFactory.Create (); + Ptr > queueB = m_queueFactory.Create > (); devB->SetQueue (queueB); // If MPI is enabled, we need to see if both nodes have the same system id // (rank), and the rank is the same as this instance. If both are true, diff --git a/src/point-to-point/helper/point-to-point-helper.h b/src/point-to-point/helper/point-to-point-helper.h index 720a3ac22..5ac2f8db3 100644 --- a/src/point-to-point/helper/point-to-point-helper.h +++ b/src/point-to-point/helper/point-to-point-helper.h @@ -30,7 +30,6 @@ namespace ns3 { -class Queue; class NetDevice; class Node; diff --git a/src/point-to-point/model/point-to-point-net-device.cc b/src/point-to-point/model/point-to-point-net-device.cc index 5faacc472..2ab1ca9b8 100644 --- a/src/point-to-point/model/point-to-point-net-device.cc +++ b/src/point-to-point/model/point-to-point-net-device.cc @@ -25,6 +25,7 @@ #include "ns3/trace-source-accessor.h" #include "ns3/uinteger.h" #include "ns3/pointer.h" +#include "ns3/net-device-queue-interface.h" #include "point-to-point-net-device.h" #include "point-to-point-channel.h" #include "ppp-header.h" @@ -76,7 +77,7 @@ PointToPointNetDevice::GetTypeId (void) "A queue to use as the transmit queue in the device.", PointerValue (), MakePointerAccessor (&PointToPointNetDevice::m_queue), - MakePointerChecker ()) + MakePointerChecker > ()) // // Trace sources at the "top" of the net device, where packets transition @@ -305,8 +306,8 @@ PointToPointNetDevice::TransmitComplete (void) txq = m_queueInterface->GetTxQueue (0); } - Ptr item = m_queue->Dequeue (); - if (item == 0) + Ptr p = m_queue->Dequeue (); + if (p == 0) { NS_LOG_LOGIC ("No pending packets in device queue after tx complete"); if (txq) @@ -327,9 +328,9 @@ PointToPointNetDevice::TransmitComplete (void) // if (txq && txq->IsStopped ()) { - if ((m_queue->GetMode () == Queue::QUEUE_MODE_PACKETS && + if ((m_queue->GetMode () == QueueBase::QUEUE_MODE_PACKETS && m_queue->GetNPackets () < m_queue->GetMaxPackets ()) || - (m_queue->GetMode () == Queue::QUEUE_MODE_BYTES && + (m_queue->GetMode () == QueueBase::QUEUE_MODE_BYTES && m_queue->GetNBytes () + m_mtu <= m_queue->GetMaxBytes ())) { NS_LOG_DEBUG ("The device queue is being started (" << m_queue->GetNPackets () << @@ -337,7 +338,6 @@ PointToPointNetDevice::TransmitComplete (void) txq->Start (); } } - Ptr p = item->GetPacket (); m_snifferTrace (p); m_promiscSnifferTrace (p); TransmitStart (p); @@ -367,7 +367,7 @@ PointToPointNetDevice::Attach (Ptr ch) } void -PointToPointNetDevice::SetQueue (Ptr q) +PointToPointNetDevice::SetQueue (Ptr > q) { NS_LOG_FUNCTION (this << q); m_queue = q; @@ -430,7 +430,7 @@ PointToPointNetDevice::Receive (Ptr packet) } } -Ptr +Ptr > PointToPointNetDevice::GetQueue (void) const { NS_LOG_FUNCTION (this); @@ -594,7 +594,7 @@ PointToPointNetDevice::Send ( // // We should enqueue and dequeue the packet to hit the tracing hooks. // - if (m_queue->Enqueue (Create (packet))) + if (m_queue->Enqueue (packet)) { // Inform BQL if (txq) @@ -606,14 +606,14 @@ PointToPointNetDevice::Send ( // if (m_txMachineState == READY) { - packet = m_queue->Dequeue ()->GetPacket (); + packet = m_queue->Dequeue (); // We have enqueued a packet and dequeued a (possibly different) packet. We // need to check if there is still room for another packet only if the queue // is in byte mode (the enqueued packet might be larger than the dequeued // packet, thus leaving no room for another packet) if (txq) { - if (m_queue->GetMode () == Queue::QUEUE_MODE_BYTES && + if (m_queue->GetMode () == QueueBase::QUEUE_MODE_BYTES && m_queue->GetNBytes () + m_mtu > m_queue->GetMaxBytes ()) { NS_LOG_DEBUG ("The device queue is being stopped (" << m_queue->GetNPackets () << @@ -636,9 +636,9 @@ PointToPointNetDevice::Send ( // we stop the queue if (txq) { - if ((m_queue->GetMode () == Queue::QUEUE_MODE_PACKETS && + if ((m_queue->GetMode () == QueueBase::QUEUE_MODE_PACKETS && m_queue->GetNPackets () >= m_queue->GetMaxPackets ()) || - (m_queue->GetMode () == Queue::QUEUE_MODE_BYTES && + (m_queue->GetMode () == QueueBase::QUEUE_MODE_BYTES && m_queue->GetNBytes () + m_mtu > m_queue->GetMaxBytes ())) { NS_LOG_DEBUG ("The device queue is being stopped (" << m_queue->GetNPackets () << diff --git a/src/point-to-point/model/point-to-point-net-device.h b/src/point-to-point/model/point-to-point-net-device.h index e2e8803fe..e60c60e5f 100644 --- a/src/point-to-point/model/point-to-point-net-device.h +++ b/src/point-to-point/model/point-to-point-net-device.h @@ -33,7 +33,8 @@ namespace ns3 { -class Queue; +template class Queue; +class NetDeviceQueueInterface; class PointToPointChannel; class ErrorModel; @@ -118,14 +119,14 @@ public: * * \param queue Ptr to the new queue. */ - void SetQueue (Ptr queue); + void SetQueue (Ptr > queue); /** * Get a copy of the attached Queue. * * \returns Ptr to the queue. */ - Ptr GetQueue (void) const; + Ptr > GetQueue (void) const; /** * Attach a receive ErrorModel to the PointToPointNetDevice. @@ -321,7 +322,7 @@ private: * and it has the responsibility for deletion. * \see class DropTailQueue */ - Ptr m_queue; + Ptr > m_queue; /** * Error model for receive packet events diff --git a/src/point-to-point/test/point-to-point-test.cc b/src/point-to-point/test/point-to-point-test.cc index 95320de40..a02671cde 100644 --- a/src/point-to-point/test/point-to-point-test.cc +++ b/src/point-to-point/test/point-to-point-test.cc @@ -23,6 +23,7 @@ #include "ns3/simulator.h" #include "ns3/point-to-point-net-device.h" #include "ns3/point-to-point-channel.h" +#include "ns3/net-device-queue-interface.h" using namespace ns3; @@ -78,10 +79,10 @@ PointToPointTest::DoRun (void) devA->Attach (channel); devA->SetAddress (Mac48Address::Allocate ()); - devA->SetQueue (CreateObject ()); + devA->SetQueue (CreateObject > ()); devB->Attach (channel); devB->SetAddress (Mac48Address::Allocate ()); - devB->SetQueue (CreateObject ()); + devB->SetQueue (CreateObject > ()); a->AddDevice (devA); b->AddDevice (devB); diff --git a/src/spectrum/helper/adhoc-aloha-noack-ideal-phy-helper.cc b/src/spectrum/helper/adhoc-aloha-noack-ideal-phy-helper.cc index 196a16c01..a17424ba4 100644 --- a/src/spectrum/helper/adhoc-aloha-noack-ideal-phy-helper.cc +++ b/src/spectrum/helper/adhoc-aloha-noack-ideal-phy-helper.cc @@ -42,7 +42,7 @@ AdhocAlohaNoackIdealPhyHelper::AdhocAlohaNoackIdealPhyHelper () { m_phy.SetTypeId ("ns3::HalfDuplexIdealPhy"); m_device.SetTypeId ("ns3::AlohaNoackNetDevice"); - m_queue.SetTypeId ("ns3::DropTailQueue"); + m_queue.SetTypeId ("ns3::DropTailQueue"); m_antenna.SetTypeId ("ns3::IsotropicAntennaModel"); } @@ -124,7 +124,7 @@ AdhocAlohaNoackIdealPhyHelper::Install (NodeContainer c) const Ptr dev = (m_device.Create ())->GetObject (); dev->SetAddress (Mac48Address::Allocate ()); - Ptr q = (m_queue.Create ())->GetObject (); + Ptr > q = (m_queue.Create ())->GetObject > (); dev->SetQueue (q); // note that we could have used a SpectrumPhyHelper here, but diff --git a/src/spectrum/model/aloha-noack-net-device.cc b/src/spectrum/model/aloha-noack-net-device.cc index dba6eb766..5a51b16c1 100644 --- a/src/spectrum/model/aloha-noack-net-device.cc +++ b/src/spectrum/model/aloha-noack-net-device.cc @@ -77,7 +77,7 @@ AlohaNoackNetDevice::GetTypeId (void) "packets being transmitted get queued here", PointerValue (), MakePointerAccessor (&AlohaNoackNetDevice::m_queue), - MakePointerChecker ()) + MakePointerChecker > ()) .AddAttribute ("Mtu", "The Maximum Transmission Unit", UintegerValue (1500), MakeUintegerAccessor (&AlohaNoackNetDevice::SetMtu, @@ -173,7 +173,7 @@ AlohaNoackNetDevice::GetMtu (void) const void -AlohaNoackNetDevice::SetQueue (Ptr q) +AlohaNoackNetDevice::SetQueue (Ptr > q) { NS_LOG_FUNCTION (q); m_queue = q; @@ -378,7 +378,7 @@ AlohaNoackNetDevice::SendFrom (Ptr packet, const Address& src, const Add else { NS_LOG_LOGIC ("enqueueing new packet"); - if (m_queue->Enqueue (Create (packet)) == false) + if (m_queue->Enqueue (packet) == false) { m_macTxDropTrace (packet); sendOk = false; @@ -389,7 +389,7 @@ AlohaNoackNetDevice::SendFrom (Ptr packet, const Address& src, const Add { NS_LOG_LOGIC ("deferring TX, enqueueing new packet"); NS_ASSERT (m_queue); - if (m_queue->Enqueue (Create (packet)) == false) + if (m_queue->Enqueue (packet) == false) { m_macTxDropTrace (packet); sendOk = false; @@ -434,9 +434,9 @@ AlohaNoackNetDevice::NotifyTransmissionEnd (Ptr) NS_ASSERT (m_queue); if (m_queue->IsEmpty () == false) { - Ptr item = m_queue->Dequeue (); - NS_ASSERT (item); - m_currentPkt = item->GetPacket (); + Ptr p = m_queue->Dequeue (); + NS_ASSERT (p); + m_currentPkt = p; NS_LOG_LOGIC ("scheduling transmission now"); Simulator::ScheduleNow (&AlohaNoackNetDevice::StartTransmission, this); } diff --git a/src/spectrum/model/aloha-noack-net-device.h b/src/spectrum/model/aloha-noack-net-device.h index 00077b747..76f734740 100644 --- a/src/spectrum/model/aloha-noack-net-device.h +++ b/src/spectrum/model/aloha-noack-net-device.h @@ -39,7 +39,7 @@ namespace ns3 { class SpectrumChannel; class Channel; class SpectrumErrorModel; -class Queue; +template class Queue; @@ -84,7 +84,7 @@ public: * * @param queue */ - virtual void SetQueue (Ptr queue); + virtual void SetQueue (Ptr > queue); /** @@ -196,7 +196,7 @@ private: void StartTransmission (); - Ptr m_queue; //!< packet queue + Ptr > m_queue; //!< packet queue TracedCallback > m_macTxTrace; //!< Tx trace TracedCallback > m_macTxDropTrace; //!< Tx Drop trace diff --git a/src/spectrum/model/non-communicating-net-device.cc b/src/spectrum/model/non-communicating-net-device.cc index c4932c552..67ab525fe 100644 --- a/src/spectrum/model/non-communicating-net-device.cc +++ b/src/spectrum/model/non-communicating-net-device.cc @@ -19,7 +19,6 @@ */ #include "ns3/log.h" -#include "ns3/queue.h" #include "ns3/simulator.h" #include "ns3/enum.h" #include "ns3/boolean.h" diff --git a/src/spectrum/model/non-communicating-net-device.h b/src/spectrum/model/non-communicating-net-device.h index e07c3c7e3..b805fa1b4 100644 --- a/src/spectrum/model/non-communicating-net-device.h +++ b/src/spectrum/model/non-communicating-net-device.h @@ -36,7 +36,6 @@ namespace ns3 { class SpectrumChannel; class Channel; class SpectrumErrorModel; -class Queue; diff --git a/src/test/ns3tc/pfifo-fast-queue-disc-test-suite.cc b/src/test/ns3tc/pfifo-fast-queue-disc-test-suite.cc index 2292fcd61..f21f547ff 100644 --- a/src/test/ns3tc/pfifo-fast-queue-disc-test-suite.cc +++ b/src/test/ns3tc/pfifo-fast-queue-disc-test-suite.cc @@ -78,7 +78,7 @@ PfifoFastQueueDiscTosPrioritization::DoRun (void) Ptr queueDisc = CreateObject (); for (uint16_t i = 0; i < 3; i++) { - Ptr queue = CreateObject (); + Ptr > queue = CreateObject > (); bool ok = queue->SetAttributeFailSafe ("MaxPackets", UintegerValue (1000)); NS_TEST_ASSERT_MSG_EQ (ok, true, "unable to set attribute"); queueDisc->AddInternalQueue (queue); @@ -154,7 +154,7 @@ PfifoFastQueueDiscDscpPrioritization::DoRun (void) Ptr queueDisc = CreateObject (); for (uint16_t i = 0; i < 3; i++) { - Ptr queue = CreateObject (); + Ptr > queue = CreateObject > (); bool ok = queue->SetAttributeFailSafe ("MaxPackets", UintegerValue (1000)); NS_TEST_ASSERT_MSG_EQ (ok, true, "unable to set attribute"); queueDisc->AddInternalQueue (queue); @@ -230,9 +230,9 @@ void PfifoFastQueueDiscOverflow::DoRun (void) { Ptr queueDisc = CreateObjectWithAttributes ("Limit", UintegerValue (6)); - Ptr band0 = CreateObjectWithAttributes ("MaxPackets", UintegerValue (6)); - Ptr band1 = CreateObjectWithAttributes ("MaxPackets", UintegerValue (6)); - Ptr band2 = CreateObjectWithAttributes ("MaxPackets", UintegerValue (6)); + Ptr > band0 = CreateObjectWithAttributes > ("MaxPackets", UintegerValue (6)); + Ptr > band1 = CreateObjectWithAttributes > ("MaxPackets", UintegerValue (6)); + Ptr > band2 = CreateObjectWithAttributes > ("MaxPackets", UintegerValue (6)); queueDisc->AddInternalQueue (band0); queueDisc->AddInternalQueue (band1); queueDisc->AddInternalQueue (band2); @@ -289,7 +289,7 @@ PfifoFastQueueDiscNoPriority::DoRun (void) Ptr queueDisc = CreateObject (); for (uint16_t i = 0; i < 3; i++) { - Ptr queue = CreateObject (); + Ptr > queue = CreateObject > (); bool ok = queue->SetAttributeFailSafe ("MaxPackets", UintegerValue (1000)); NS_TEST_ASSERT_MSG_EQ (ok, true, "unable to set attribute"); queueDisc->AddInternalQueue (queue); diff --git a/src/test/ns3tcp/ns3tcp-state-test-suite.cc b/src/test/ns3tcp/ns3tcp-state-test-suite.cc index de5efbc52..959c63ce8 100644 --- a/src/test/ns3tcp/ns3tcp-state-test-suite.cc +++ b/src/test/ns3tcp/ns3tcp-state-test-suite.cc @@ -307,7 +307,7 @@ Ns3TcpStateTestCase::DoRun (void) Config::SetDefault ("ns3::TcpL4Protocol::SocketType", StringValue (tcpModel)); Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (1000)); Config::SetDefault ("ns3::TcpSocket::DelAckCount", UintegerValue (1)); - Config::SetDefault ("ns3::Queue::MaxPackets", UintegerValue (20)); + Config::SetDefault ("ns3::QueueBase::MaxPackets", UintegerValue (20)); Config::SetDefault ("ns3::TcpSocketBase::Timestamp", BooleanValue (false)); if (m_writeLogging) diff --git a/src/traffic-control/examples/adaptive-red-tests.cc b/src/traffic-control/examples/adaptive-red-tests.cc index 8786ef5a6..d3dc2f15c 100644 --- a/src/traffic-control/examples/adaptive-red-tests.cc +++ b/src/traffic-control/examples/adaptive-red-tests.cc @@ -240,7 +240,7 @@ main (int argc, char *argv[]) // RED params NS_LOG_INFO ("Set RED params"); - Config::SetDefault ("ns3::RedQueueDisc::Mode", StringValue ("QUEUE_MODE_PACKETS")); + Config::SetDefault ("ns3::RedQueueDisc::Mode", StringValue ("QUEUE_DISC_MODE_PACKETS")); Config::SetDefault ("ns3::RedQueueDisc::MeanPktSize", UintegerValue (meanPktSize)); Config::SetDefault ("ns3::RedQueueDisc::Wait", BooleanValue (true)); Config::SetDefault ("ns3::RedQueueDisc::Gentle", BooleanValue (true)); diff --git a/src/traffic-control/examples/codel-vs-pfifo-asymmetric.cc b/src/traffic-control/examples/codel-vs-pfifo-asymmetric.cc index 717b44ad0..d0ee361b3 100644 --- a/src/traffic-control/examples/codel-vs-pfifo-asymmetric.cc +++ b/src/traffic-control/examples/codel-vs-pfifo-asymmetric.cc @@ -136,7 +136,7 @@ TraceQueueLength (std::string queueLengthTrFileName) } static void -EveryDropTracer (Ptrstream, Ptr item) +EveryDropTracer (Ptrstream, Ptr item) { *stream->GetStream () << Simulator::Now ().GetSeconds () << " " << item << std::endl; } @@ -282,7 +282,7 @@ int main (int argc, char *argv[]) // Queue defaults Config::SetDefault ("ns3::PfifoFastQueueDisc::Limit", UintegerValue (queueSize)); Config::SetDefault ("ns3::CoDelQueueDisc::MaxPackets", UintegerValue (queueSize)); - Config::SetDefault ("ns3::CoDelQueueDisc::Mode", StringValue ("QUEUE_MODE_PACKETS")); + Config::SetDefault ("ns3::CoDelQueueDisc::Mode", StringValue ("QUEUE_DISC_MODE_PACKETS")); // Create the nodes NS_LOG_INFO ("Create nodes"); diff --git a/src/traffic-control/examples/codel-vs-pfifo-basic-test.cc b/src/traffic-control/examples/codel-vs-pfifo-basic-test.cc index 9ab2f00a4..fb1e6c751 100644 --- a/src/traffic-control/examples/codel-vs-pfifo-basic-test.cc +++ b/src/traffic-control/examples/codel-vs-pfifo-basic-test.cc @@ -126,8 +126,8 @@ int main (int argc, char *argv[]) GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true)); } - Config::SetDefault ("ns3::Queue::Mode", StringValue ("QUEUE_MODE_PACKETS")); - Config::SetDefault ("ns3::Queue::MaxPackets", UintegerValue (queueSize)); + Config::SetDefault ("ns3::QueueBase::Mode", StringValue ("QUEUE_MODE_PACKETS")); + Config::SetDefault ("ns3::QueueBase::MaxPackets", UintegerValue (queueSize)); // Create gateway, source, and sink NodeContainer gateway; diff --git a/src/traffic-control/examples/pfifo-vs-red.cc b/src/traffic-control/examples/pfifo-vs-red.cc index f9c29674b..fee10cd66 100644 --- a/src/traffic-control/examples/pfifo-vs-red.cc +++ b/src/traffic-control/examples/pfifo-vs-red.cc @@ -70,18 +70,18 @@ int main (int argc, char *argv[]) Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (pktSize)); Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue (appDataRate)); - Config::SetDefault ("ns3::Queue::Mode", StringValue ("QUEUE_MODE_PACKETS")); - Config::SetDefault ("ns3::Queue::MaxPackets", UintegerValue (maxPackets)); + Config::SetDefault ("ns3::QueueBase::Mode", StringValue ("QUEUE_MODE_PACKETS")); + Config::SetDefault ("ns3::QueueBase::MaxPackets", UintegerValue (maxPackets)); if (!modeBytes) { - Config::SetDefault ("ns3::RedQueueDisc::Mode", StringValue ("QUEUE_MODE_PACKETS")); + Config::SetDefault ("ns3::RedQueueDisc::Mode", StringValue ("QUEUE_DISC_MODE_PACKETS")); Config::SetDefault ("ns3::RedQueueDisc::QueueLimit", UintegerValue (queueDiscLimitPackets)); Config::SetDefault ("ns3::PfifoFastQueueDisc::Limit", UintegerValue (queueDiscLimitPackets)); } else { - Config::SetDefault ("ns3::RedQueueDisc::Mode", StringValue ("QUEUE_MODE_BYTES")); + Config::SetDefault ("ns3::RedQueueDisc::Mode", StringValue ("QUEUE_DISC_MODE_BYTES")); Config::SetDefault ("ns3::RedQueueDisc::QueueLimit", UintegerValue (queueDiscLimitPackets * pktSize)); minTh *= pktSize; maxTh *= pktSize; diff --git a/src/traffic-control/examples/red-tests.cc b/src/traffic-control/examples/red-tests.cc index ecf1e15e8..d96ab0f3f 100644 --- a/src/traffic-control/examples/red-tests.cc +++ b/src/traffic-control/examples/red-tests.cc @@ -317,7 +317,7 @@ main (int argc, char *argv[]) // RED params NS_LOG_INFO ("Set RED params"); - Config::SetDefault ("ns3::RedQueueDisc::Mode", StringValue ("QUEUE_MODE_PACKETS")); + Config::SetDefault ("ns3::RedQueueDisc::Mode", StringValue ("QUEUE_DISC_MODE_PACKETS")); Config::SetDefault ("ns3::RedQueueDisc::MeanPktSize", UintegerValue (meanPktSize)); Config::SetDefault ("ns3::RedQueueDisc::Wait", BooleanValue (true)); Config::SetDefault ("ns3::RedQueueDisc::Gentle", BooleanValue (true)); @@ -333,7 +333,7 @@ main (int argc, char *argv[]) } else if (redTest == 5) // test 5, same of test 4, but in byte mode { - Config::SetDefault ("ns3::RedQueueDisc::Mode", StringValue ("QUEUE_MODE_BYTES")); + Config::SetDefault ("ns3::RedQueueDisc::Mode", StringValue ("QUEUE_DISC_MODE_BYTES")); Config::SetDefault ("ns3::RedQueueDisc::Ns1Compat", BooleanValue (true)); Config::SetDefault ("ns3::RedQueueDisc::MinTh", DoubleValue (5 * meanPktSize)); Config::SetDefault ("ns3::RedQueueDisc::MaxTh", DoubleValue (15 * meanPktSize)); @@ -412,7 +412,7 @@ main (int argc, char *argv[]) // like in ns2 test, r2 -> r1, have a queue in packet mode Ptr queue = queueDiscs.Get (1); - StaticCast (queue)->SetMode (Queue::QUEUE_MODE_PACKETS); + StaticCast (queue)->SetMode (RedQueueDisc::QUEUE_DISC_MODE_PACKETS); StaticCast (queue)->SetTh (5, 15); StaticCast (queue)->SetQueueLimit (1000); } diff --git a/src/traffic-control/examples/red-vs-ared.cc b/src/traffic-control/examples/red-vs-ared.cc index d67972e9d..9ff14cdf7 100644 --- a/src/traffic-control/examples/red-vs-ared.cc +++ b/src/traffic-control/examples/red-vs-ared.cc @@ -70,17 +70,17 @@ int main (int argc, char *argv[]) Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (pktSize)); Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue (appDataRate)); - Config::SetDefault ("ns3::Queue::Mode", StringValue ("QUEUE_MODE_PACKETS")); - Config::SetDefault ("ns3::Queue::MaxPackets", UintegerValue (maxPackets)); + Config::SetDefault ("ns3::QueueBase::Mode", StringValue ("QUEUE_MODE_PACKETS")); + Config::SetDefault ("ns3::QueueBase::MaxPackets", UintegerValue (maxPackets)); if (!modeBytes) { - Config::SetDefault ("ns3::RedQueueDisc::Mode", StringValue ("QUEUE_MODE_PACKETS")); + Config::SetDefault ("ns3::RedQueueDisc::Mode", StringValue ("QUEUE_DISC_MODE_PACKETS")); Config::SetDefault ("ns3::RedQueueDisc::QueueLimit", UintegerValue (queueDiscLimitPackets)); } else { - Config::SetDefault ("ns3::RedQueueDisc::Mode", StringValue ("QUEUE_MODE_BYTES")); + Config::SetDefault ("ns3::RedQueueDisc::Mode", StringValue ("QUEUE_DISC_MODE_BYTES")); Config::SetDefault ("ns3::RedQueueDisc::QueueLimit", UintegerValue (queueDiscLimitPackets * pktSize)); minTh *= pktSize; maxTh *= pktSize; diff --git a/src/traffic-control/helper/traffic-control-helper.cc b/src/traffic-control/helper/traffic-control-helper.cc index 48efdc2cc..38c51c656 100644 --- a/src/traffic-control/helper/traffic-control-helper.cc +++ b/src/traffic-control/helper/traffic-control-helper.cc @@ -20,8 +20,9 @@ #include "ns3/log.h" #include "ns3/abort.h" -#include "ns3/queue-disc.h" #include "ns3/queue-limits.h" +#include "ns3/queue.h" +#include "ns3/net-device-queue-interface.h" #include "ns3/uinteger.h" #include "ns3/pointer.h" #include "ns3/traffic-control-layer.h" @@ -73,7 +74,7 @@ QueueDiscFactory::CreateQueueDisc (const std::vector > & queueDis for (std::vector::iterator i = m_internalQueuesFactory.begin (); i != m_internalQueuesFactory.end (); i++ ) { - qd->AddInternalQueue (i->Create ()); + qd->AddInternalQueue (i->Create ()); } // create and add the packet filters @@ -170,6 +171,8 @@ TrafficControlHelper::AddInternalQueues (uint16_t handle, uint16_t count, std::s NS_ABORT_MSG_IF (handle >= m_queueDiscFactory.size (), "A queue disc with handle " << handle << " does not exist"); + QueueBase::AppendItemTypeIfNotPresent (type, "QueueDiscItem"); + ObjectFactory factory; factory.SetTypeId (type); factory.Set (n01, v01); @@ -386,6 +389,8 @@ TrafficControlHelper::Install (Ptr d) { Ptr ndqi = d->GetObject (); NS_ASSERT (ndqi); + NS_ABORT_MSG_IF (ndqi->GetNTxQueues () == 0, "Could not install QueueLimits" + << "because the TX queues have not been created yet"); for (uint8_t i = 0; i < ndqi->GetNTxQueues (); i++) { Ptr ql = m_queueLimitsFactory.Create (); diff --git a/src/traffic-control/helper/traffic-control-helper.h b/src/traffic-control/helper/traffic-control-helper.h index 6b4ba1004..b89514693 100644 --- a/src/traffic-control/helper/traffic-control-helper.h +++ b/src/traffic-control/helper/traffic-control-helper.h @@ -29,8 +29,6 @@ namespace ns3 { -class QueueDisc; - /** * \ingroup traffic-control * diff --git a/src/traffic-control/model/codel-queue-disc.cc b/src/traffic-control/model/codel-queue-disc.cc index d0d5f65cf..6ffae47ff 100644 --- a/src/traffic-control/model/codel-queue-disc.cc +++ b/src/traffic-control/model/codel-queue-disc.cc @@ -32,6 +32,7 @@ #include "codel-queue-disc.h" #include "ns3/object-factory.h" #include "ns3/drop-tail-queue.h" +#include "ns3/net-device-queue-interface.h" namespace ns3 { @@ -154,10 +155,10 @@ TypeId CoDelQueueDisc::GetTypeId (void) .AddConstructor () .AddAttribute ("Mode", "Whether to use Bytes (see MaxBytes) or Packets (see MaxPackets) as the maximum queue size metric.", - EnumValue (Queue::QUEUE_MODE_BYTES), + EnumValue (QUEUE_DISC_MODE_BYTES), MakeEnumAccessor (&CoDelQueueDisc::SetMode), - MakeEnumChecker (Queue::QUEUE_MODE_BYTES, "QUEUE_MODE_BYTES", - Queue::QUEUE_MODE_PACKETS, "QUEUE_MODE_PACKETS")) + MakeEnumChecker (QUEUE_DISC_MODE_BYTES, "QUEUE_DISC_MODE_BYTES", + QUEUE_DISC_MODE_PACKETS, "QUEUE_DISC_MODE_PACKETS")) .AddAttribute ("MaxPackets", "The maximum number of packets accepted by this CoDelQueueDisc.", UintegerValue (DEFAULT_CODEL_LIMIT), @@ -258,13 +259,13 @@ CoDelQueueDisc::ControlLaw (uint32_t t) } void -CoDelQueueDisc::SetMode (Queue::QueueMode mode) +CoDelQueueDisc::SetMode (QueueDiscMode mode) { NS_LOG_FUNCTION (mode); m_mode = mode; } -Queue::QueueMode +CoDelQueueDisc::QueueDiscMode CoDelQueueDisc::GetMode (void) { NS_LOG_FUNCTION (this); @@ -277,7 +278,7 @@ CoDelQueueDisc::DoEnqueue (Ptr item) NS_LOG_FUNCTION (this << item); Ptr p = item->GetPacket (); - if (m_mode == Queue::QUEUE_MODE_PACKETS && (GetInternalQueue (0)->GetNPackets () + 1 > m_maxPackets)) + if (m_mode == QUEUE_DISC_MODE_PACKETS && (GetInternalQueue (0)->GetNPackets () + 1 > m_maxPackets)) { NS_LOG_LOGIC ("Queue full (at max packets) -- droppping pkt"); Drop (item); @@ -285,7 +286,7 @@ CoDelQueueDisc::DoEnqueue (Ptr item) return false; } - if (m_mode == Queue::QUEUE_MODE_BYTES && (GetInternalQueue (0)->GetNBytes () + item->GetPacketSize () > m_maxBytes)) + if (m_mode == QUEUE_DISC_MODE_BYTES && (GetInternalQueue (0)->GetNBytes () + item->GetSize () > m_maxBytes)) { NS_LOG_LOGIC ("Queue full (packet would exceed max bytes) -- droppping pkt"); Drop (item); @@ -360,7 +361,7 @@ CoDelQueueDisc::DoDequeue (void) { NS_LOG_FUNCTION (this); - Ptr item = StaticCast (GetInternalQueue (0)->Dequeue ()); + Ptr item = GetInternalQueue (0)->Dequeue (); if (!item) { // Leave dropping state when queue is empty @@ -404,7 +405,7 @@ CoDelQueueDisc::DoDequeue (void) ++m_dropCount; ++m_count; NewtonStep (); - item = StaticCast (GetInternalQueue (0)->Dequeue ()); + item = GetInternalQueue (0)->Dequeue (); if (item) { @@ -441,7 +442,7 @@ CoDelQueueDisc::DoDequeue (void) ++m_dropCount; Drop (item); - item = StaticCast (GetInternalQueue (0)->Dequeue ()); + item = GetInternalQueue (0)->Dequeue (); if (item) { @@ -483,11 +484,11 @@ uint32_t CoDelQueueDisc::GetQueueSize (void) { NS_LOG_FUNCTION (this); - if (GetMode () == Queue::QUEUE_MODE_BYTES) + if (GetMode () == QUEUE_DISC_MODE_BYTES) { return GetInternalQueue (0)->GetNBytes (); } - else if (GetMode () == Queue::QUEUE_MODE_PACKETS) + else if (GetMode () == QUEUE_DISC_MODE_PACKETS) { return GetInternalQueue (0)->GetNPackets (); } @@ -538,7 +539,7 @@ CoDelQueueDisc::DoPeek (void) const return 0; } - Ptr item = StaticCast (GetInternalQueue (0)->Peek ()); + Ptr item = GetInternalQueue (0)->Peek (); NS_LOG_LOGIC ("Number packets " << GetInternalQueue (0)->GetNPackets ()); NS_LOG_LOGIC ("Number bytes " << GetInternalQueue (0)->GetNBytes ()); @@ -595,8 +596,8 @@ CoDelQueueDisc::CheckConfig (void) if (GetNInternalQueues () == 0) { // create a DropTail queue - Ptr queue = CreateObjectWithAttributes ("Mode", EnumValue (m_mode)); - if (m_mode == Queue::QUEUE_MODE_PACKETS) + Ptr queue = CreateObjectWithAttributes > ("Mode", EnumValue (m_mode)); + if (m_mode == QUEUE_DISC_MODE_PACKETS) { queue->SetMaxPackets (m_maxPackets); } @@ -613,14 +614,15 @@ CoDelQueueDisc::CheckConfig (void) return false; } - if (GetInternalQueue (0)->GetMode () != m_mode) + if ((GetInternalQueue (0)->GetMode () == QueueBase::QUEUE_MODE_PACKETS && m_mode == QUEUE_DISC_MODE_BYTES) || + (GetInternalQueue (0)->GetMode () == QueueBase::QUEUE_MODE_BYTES && m_mode == QUEUE_DISC_MODE_PACKETS)) { NS_LOG_ERROR ("The mode of the provided queue does not match the mode set on the CoDelQueueDisc"); return false; } - if ((m_mode == Queue::QUEUE_MODE_PACKETS && GetInternalQueue (0)->GetMaxPackets () < m_maxPackets) || - (m_mode == Queue::QUEUE_MODE_BYTES && GetInternalQueue (0)->GetMaxBytes () < m_maxBytes)) + if ((m_mode == QUEUE_DISC_MODE_PACKETS && GetInternalQueue (0)->GetMaxPackets () < m_maxPackets) || + (m_mode == QUEUE_DISC_MODE_BYTES && GetInternalQueue (0)->GetMaxBytes () < m_maxBytes)) { NS_LOG_ERROR ("The size of the internal queue is less than the queue disc limit"); return false; diff --git a/src/traffic-control/model/codel-queue-disc.h b/src/traffic-control/model/codel-queue-disc.h index 09a9e39d8..caa0504f1 100644 --- a/src/traffic-control/model/codel-queue-disc.h +++ b/src/traffic-control/model/codel-queue-disc.h @@ -28,7 +28,6 @@ #ifndef CODEL_H #define CODEL_H -#include "ns3/packet.h" #include "ns3/queue-disc.h" #include "ns3/nstime.h" #include "ns3/simulator.h" @@ -79,18 +78,28 @@ public: virtual ~CoDelQueueDisc (); /** - * \brief Set the operating mode of this device. + * \brief Enumeration of the modes supported in the class. * - * \param mode The operating mode of this device. */ - void SetMode (Queue::QueueMode mode); + enum QueueDiscMode + { + QUEUE_DISC_MODE_PACKETS, /**< Use number of packets for maximum queue disc size */ + QUEUE_DISC_MODE_BYTES, /**< Use number of bytes for maximum queue disc size */ + }; /** - * \brief Get the encapsulation mode of this device. + * \brief Set the operating mode of this queue disc. * - * \returns The encapsulation mode of this device. + * \param mode The operating mode of this queue disc. */ - Queue::QueueMode GetMode (void); + void SetMode (QueueDiscMode mode); + + /** + * \brief Get the operating mode of this queue disc. + * + * \returns The operating mode of this queue disc. + */ + QueueDiscMode GetMode (void); /** * \brief Get the current value of the queue in bytes or packets. @@ -242,7 +251,7 @@ private: uint32_t m_state3; //!< Number of times we enter drop state and drop the fist packet uint32_t m_states; //!< Total number of times we are in state 1, state 2, or state 3 uint32_t m_dropOverLimit; //!< The number of packets dropped due to full queue - Queue::QueueMode m_mode; //!< The operating mode (Bytes or packets) + QueueDiscMode m_mode; //!< The operating mode (Bytes or packets) TracedValue