network: The Queue base class holds mode, maxPackets and maxBytes
...so that all the subclasses have such attributes. This allows queue discs to have attributes specifying the mode and size of their queue(s) and to create queues using their own attributes. This commit is heavily inspired by Natale's queue rework patch: https://codereview.appspot.com/270540044/
This commit is contained in:
@@ -17,8 +17,6 @@
|
||||
*/
|
||||
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/enum.h"
|
||||
#include "ns3/uinteger.h"
|
||||
#include "drop-tail-queue.h"
|
||||
|
||||
namespace ns3 {
|
||||
@@ -27,38 +25,19 @@ NS_LOG_COMPONENT_DEFINE ("DropTailQueue");
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (DropTailQueue);
|
||||
|
||||
TypeId DropTailQueue::GetTypeId (void)
|
||||
TypeId DropTailQueue::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::DropTailQueue")
|
||||
.SetParent<Queue> ()
|
||||
.SetGroupName("Network")
|
||||
.SetGroupName ("Network")
|
||||
.AddConstructor<DropTailQueue> ()
|
||||
.AddAttribute ("Mode",
|
||||
"Whether to use bytes (see MaxBytes) or packets (see MaxPackets) as the maximum queue size metric.",
|
||||
EnumValue (QUEUE_MODE_PACKETS),
|
||||
MakeEnumAccessor (&DropTailQueue::SetMode,
|
||||
&DropTailQueue::GetMode),
|
||||
MakeEnumChecker (QUEUE_MODE_BYTES, "QUEUE_MODE_BYTES",
|
||||
QUEUE_MODE_PACKETS, "QUEUE_MODE_PACKETS"))
|
||||
.AddAttribute ("MaxPackets",
|
||||
"The maximum number of packets accepted by this DropTailQueue.",
|
||||
UintegerValue (100),
|
||||
MakeUintegerAccessor (&DropTailQueue::m_maxPackets),
|
||||
MakeUintegerChecker<uint32_t> ())
|
||||
.AddAttribute ("MaxBytes",
|
||||
"The maximum number of bytes accepted by this DropTailQueue.",
|
||||
UintegerValue (100 * 65535),
|
||||
MakeUintegerAccessor (&DropTailQueue::m_maxBytes),
|
||||
MakeUintegerChecker<uint32_t> ())
|
||||
;
|
||||
|
||||
return tid;
|
||||
}
|
||||
|
||||
DropTailQueue::DropTailQueue () :
|
||||
Queue (),
|
||||
m_packets (),
|
||||
m_bytesInQueue (0)
|
||||
m_packets ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
@@ -68,46 +47,14 @@ DropTailQueue::~DropTailQueue ()
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
void
|
||||
DropTailQueue::SetMode (DropTailQueue::QueueMode mode)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << mode);
|
||||
m_mode = mode;
|
||||
}
|
||||
|
||||
DropTailQueue::QueueMode
|
||||
DropTailQueue::GetMode (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return m_mode;
|
||||
}
|
||||
|
||||
bool
|
||||
DropTailQueue::DoEnqueue (Ptr<QueueItem> item)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << item);
|
||||
Ptr<Packet> p = item->GetPacket ();
|
||||
NS_ASSERT (m_packets.size () == GetNPackets ());
|
||||
|
||||
if (m_mode == QUEUE_MODE_PACKETS && (m_packets.size () >= m_maxPackets))
|
||||
{
|
||||
NS_LOG_LOGIC ("Queue full (at max packets) -- droppping pkt");
|
||||
Drop (p);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_mode == QUEUE_MODE_BYTES && (m_bytesInQueue + item->GetPacketSize () >= m_maxBytes))
|
||||
{
|
||||
NS_LOG_LOGIC ("Queue full (packet would exceed max bytes) -- droppping pkt");
|
||||
Drop (p);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_bytesInQueue += item->GetPacketSize ();
|
||||
m_packets.push (item);
|
||||
|
||||
NS_LOG_LOGIC ("Number packets " << m_packets.size ());
|
||||
NS_LOG_LOGIC ("Number bytes " << m_bytesInQueue);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -115,22 +62,13 @@ Ptr<QueueItem>
|
||||
DropTailQueue::DoDequeue (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
if (m_packets.empty ())
|
||||
{
|
||||
NS_LOG_LOGIC ("Queue empty");
|
||||
return 0;
|
||||
}
|
||||
NS_ASSERT (m_packets.size () == GetNPackets ());
|
||||
|
||||
Ptr<QueueItem> item = m_packets.front ();
|
||||
m_packets.pop ();
|
||||
m_bytesInQueue -= item->GetPacketSize ();
|
||||
|
||||
NS_LOG_LOGIC ("Popped " << item);
|
||||
|
||||
NS_LOG_LOGIC ("Number packets " << m_packets.size ());
|
||||
NS_LOG_LOGIC ("Number bytes " << m_bytesInQueue);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@@ -138,19 +76,9 @@ Ptr<const QueueItem>
|
||||
DropTailQueue::DoPeek (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_ASSERT (m_packets.size () == GetNPackets ());
|
||||
|
||||
if (m_packets.empty ())
|
||||
{
|
||||
NS_LOG_LOGIC ("Queue empty");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Ptr<QueueItem> item = m_packets.front ();
|
||||
|
||||
NS_LOG_LOGIC ("Number packets " << m_packets.size ());
|
||||
NS_LOG_LOGIC ("Number bytes " << m_bytesInQueue);
|
||||
|
||||
return item;
|
||||
return m_packets.front ();
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -20,19 +20,17 @@
|
||||
#define DROPTAIL_H
|
||||
|
||||
#include <queue>
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/queue.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
class TraceContainer;
|
||||
|
||||
/**
|
||||
* \ingroup queue
|
||||
*
|
||||
* \brief A FIFO packet queue that drops tail-end packets on overflow
|
||||
*/
|
||||
class DropTailQueue : public Queue {
|
||||
class DropTailQueue : public Queue
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Get the type ID.
|
||||
@@ -48,31 +46,12 @@ public:
|
||||
|
||||
virtual ~DropTailQueue();
|
||||
|
||||
/**
|
||||
* Set the operating mode of this device.
|
||||
*
|
||||
* \param mode The operating mode of this device.
|
||||
*
|
||||
*/
|
||||
void SetMode (DropTailQueue::QueueMode mode);
|
||||
|
||||
/**
|
||||
* Get the encapsulation mode of this device.
|
||||
*
|
||||
* \returns The encapsulation mode of this device.
|
||||
*/
|
||||
DropTailQueue::QueueMode GetMode (void) const;
|
||||
|
||||
private:
|
||||
virtual bool DoEnqueue (Ptr<QueueItem> item);
|
||||
virtual Ptr<QueueItem> DoDequeue (void);
|
||||
virtual Ptr<const QueueItem> DoPeek (void) const;
|
||||
|
||||
std::queue<Ptr<QueueItem> > m_packets; //!< the items in the queue
|
||||
uint32_t m_maxPackets; //!< max packets in the queue
|
||||
uint32_t m_maxBytes; //!< max bytes in the queue
|
||||
uint32_t m_bytesInQueue; //!< actual bytes in the queue
|
||||
QueueMode m_mode; //!< queue mode (packets or bytes limited)
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
*/
|
||||
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/abort.h"
|
||||
#include "ns3/enum.h"
|
||||
#include "ns3/uinteger.h"
|
||||
#include "ns3/trace-source-accessor.h"
|
||||
#include "queue.h"
|
||||
|
||||
@@ -31,16 +34,43 @@ Queue::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::Queue")
|
||||
.SetParent<Object> ()
|
||||
.SetGroupName("Network")
|
||||
.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),
|
||||
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),
|
||||
MakeUintegerChecker<uint32_t> ())
|
||||
.AddAttribute ("MaxBytes",
|
||||
"The maximum number of bytes accepted by this queue.",
|
||||
UintegerValue (100 * 65535),
|
||||
MakeUintegerAccessor (&Queue::SetMaxBytes,
|
||||
&Queue::GetMaxBytes),
|
||||
MakeUintegerChecker<uint32_t> ())
|
||||
.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 stored in the queue.",
|
||||
.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),
|
||||
"ns3::TracedValueCallback::Uint32")
|
||||
.AddTraceSource ("BytesInQueue",
|
||||
"Number of bytes currently stored in the queue",
|
||||
MakeTraceSourceAccessor (&Queue::m_nBytes),
|
||||
"ns3::TracedValueCallback::Uint32")
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
@@ -51,7 +81,8 @@ Queue::Queue() :
|
||||
m_nPackets (0),
|
||||
m_nTotalReceivedPackets (0),
|
||||
m_nTotalDroppedBytes (0),
|
||||
m_nTotalDroppedPackets (0)
|
||||
m_nTotalDroppedPackets (0),
|
||||
m_mode (QUEUE_MODE_PACKETS)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
@@ -66,6 +97,21 @@ bool
|
||||
Queue::Enqueue (Ptr<QueueItem> item)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << item);
|
||||
Ptr<Packet> p = item->GetPacket ();
|
||||
|
||||
if (m_mode == QUEUE_MODE_PACKETS && (m_nPackets.Get () >= m_maxPackets))
|
||||
{
|
||||
NS_LOG_LOGIC ("Queue full (at max packets) -- dropping pkt");
|
||||
Drop (p);
|
||||
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 (p);
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// If DoEnqueue fails, Queue::Drop is called by the subclass
|
||||
@@ -91,19 +137,24 @@ Queue::Dequeue (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
if (m_nPackets.Get () == 0)
|
||||
{
|
||||
NS_LOG_LOGIC ("Queue empty");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Ptr<QueueItem> item = DoDequeue ();
|
||||
|
||||
if (item != 0)
|
||||
{
|
||||
Ptr<Packet> packet = item->GetPacket ();
|
||||
NS_ASSERT (m_nBytes >= item->GetPacketSize ());
|
||||
NS_ASSERT (m_nPackets > 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 (packet);
|
||||
m_traceDequeue (item->GetPacket ());
|
||||
}
|
||||
return item;
|
||||
}
|
||||
@@ -122,6 +173,13 @@ Ptr<const QueueItem>
|
||||
Queue::Peek (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
if (m_nPackets.Get () == 0)
|
||||
{
|
||||
NS_LOG_LOGIC ("Queue empty");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DoPeek ();
|
||||
}
|
||||
|
||||
@@ -146,8 +204,8 @@ bool
|
||||
Queue::IsEmpty (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_LOG_LOGIC ("returns " << (m_nPackets == 0));
|
||||
return m_nPackets == 0;
|
||||
NS_LOG_LOGIC ("returns " << (m_nPackets.Get () == 0));
|
||||
return m_nPackets.Get () == 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@@ -192,6 +250,74 @@ Queue::ResetStatistics (void)
|
||||
m_nTotalDroppedPackets = 0;
|
||||
}
|
||||
|
||||
void
|
||||
Queue::SetMode (Queue::QueueMode mode)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << mode);
|
||||
|
||||
if (mode == QUEUE_MODE_BYTES && m_mode == QUEUE_MODE_PACKETS)
|
||||
{
|
||||
NS_ABORT_MSG_IF (m_nPackets.Get () != 0,
|
||||
"Cannot change queue mode in a queue with packets.");
|
||||
}
|
||||
else if (mode == QUEUE_MODE_PACKETS && m_mode == QUEUE_MODE_BYTES)
|
||||
{
|
||||
NS_ABORT_MSG_IF (m_nBytes.Get () != 0,
|
||||
"Cannot change queue mode in a queue with packets.");
|
||||
}
|
||||
|
||||
m_mode = mode;
|
||||
}
|
||||
|
||||
Queue::QueueMode
|
||||
Queue::GetMode (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return m_mode;
|
||||
}
|
||||
|
||||
void
|
||||
Queue::SetMaxPackets (uint32_t maxPackets)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << maxPackets);
|
||||
|
||||
if (m_mode == QUEUE_MODE_PACKETS)
|
||||
{
|
||||
NS_ABORT_MSG_IF (maxPackets < m_nPackets.Get (),
|
||||
"The new queue size cannot be less than the number of currently stored packets.");
|
||||
}
|
||||
|
||||
m_maxPackets = maxPackets;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Queue::GetMaxPackets (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return m_maxPackets;
|
||||
}
|
||||
|
||||
void
|
||||
Queue::SetMaxBytes (uint32_t maxBytes)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << maxBytes);
|
||||
|
||||
if (m_mode == QUEUE_MODE_BYTES)
|
||||
{
|
||||
NS_ABORT_MSG_IF (maxBytes < m_nBytes.Get (),
|
||||
"The new queue size cannot be less than the amount of bytes of currently stored packets.");
|
||||
}
|
||||
|
||||
m_maxBytes = maxBytes;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Queue::GetMaxBytes (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return m_maxBytes;
|
||||
}
|
||||
|
||||
void
|
||||
Queue::Drop (Ptr<Packet> p)
|
||||
{
|
||||
|
||||
@@ -16,9 +16,8 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
// The queue base class does not have any limit based on the number
|
||||
// of packets or number of bytes. It is, conceptually, infinite
|
||||
// by default. Only subclasses define limitations.
|
||||
// The queue base class has a limit on its size, in terms of number of
|
||||
// packets or number of bytes depending on the operating mode.
|
||||
// The base class implements tracing and basic statistics calculations.
|
||||
|
||||
#ifndef QUEUE_H
|
||||
@@ -28,6 +27,7 @@
|
||||
#include "ns3/object.h"
|
||||
#include "ns3/traced-callback.h"
|
||||
#include "ns3/net-device.h"
|
||||
#include "ns3/traced-value.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
@@ -128,6 +128,44 @@ public:
|
||||
QUEUE_MODE_BYTES, /**< Use number of bytes for maximum queue size */
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the operating mode of this device.
|
||||
*
|
||||
* \param mode The operating mode of this device.
|
||||
*/
|
||||
void SetMode (Queue::QueueMode mode);
|
||||
|
||||
/**
|
||||
* Get the encapsulation mode of this device.
|
||||
*
|
||||
* \returns The encapsulation mode of this device.
|
||||
*/
|
||||
Queue::QueueMode GetMode (void) const;
|
||||
|
||||
/**
|
||||
* \brief Set the maximum amount of packets that can be stored in this queue
|
||||
*
|
||||
* \param maxPackets amount of packets
|
||||
*/
|
||||
void SetMaxPackets (uint32_t maxPackets);
|
||||
|
||||
/**
|
||||
* \return the maximum amount of packets that can be stored in this queue
|
||||
*/
|
||||
uint32_t GetMaxPackets (void) const;
|
||||
|
||||
/**
|
||||
* \brief Set the maximum amount of bytes that can be stored in this queue
|
||||
*
|
||||
* \param maxBytes amount of bytes
|
||||
*/
|
||||
void SetMaxBytes (uint32_t maxBytes);
|
||||
|
||||
/**
|
||||
* \return the maximum amount of bytes that can be stored in this queue
|
||||
*/
|
||||
uint32_t GetMaxBytes (void) const;
|
||||
|
||||
#if 0
|
||||
// average calculation requires keeping around
|
||||
// a buffer with the date of arrival of past received packets
|
||||
@@ -152,8 +190,18 @@ public:
|
||||
double GetDroppedPacketsPerSecondVariance (void);
|
||||
#endif
|
||||
|
||||
private:
|
||||
protected:
|
||||
/**
|
||||
* \brief Drop a packet
|
||||
* \param p packet 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.
|
||||
*/
|
||||
void Drop (Ptr<Packet> p);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Push an item in the queue
|
||||
* \param item the item to enqueue
|
||||
@@ -171,14 +219,6 @@ private:
|
||||
*/
|
||||
virtual Ptr<const QueueItem> DoPeek (void) const = 0;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* \brief Drop a packet
|
||||
* \param p packet that was dropped
|
||||
* This method is called by subclasses to notify parent (this class) of packet drops.
|
||||
*/
|
||||
void Drop (Ptr<Packet> p);
|
||||
|
||||
/// Traced callback: fired when a packet is enqueued
|
||||
TracedCallback<Ptr<const Packet> > m_traceEnqueue;
|
||||
/// Traced callback: fired when a packet is dequeued
|
||||
@@ -186,12 +226,16 @@ protected:
|
||||
/// Traced callback: fired when a packet is dropped
|
||||
TracedCallback<Ptr<const Packet> > m_traceDrop;
|
||||
|
||||
uint32_t m_nBytes; //!< Number of bytes in the queue
|
||||
TracedValue<uint32_t> m_nBytes; //!< Number of bytes in the queue
|
||||
uint32_t m_nTotalReceivedBytes; //!< Total received bytes
|
||||
uint32_t m_nPackets; //!< Number of packets in the queue
|
||||
TracedValue<uint32_t> 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)
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -433,7 +433,7 @@ Ns3TcpCwndTestCase2::DoRun (void)
|
||||
{
|
||||
NS_LOG_DEBUG ("Starting test case 2");
|
||||
// Set up some default values for the simulation.
|
||||
Config::SetDefault ("ns3::DropTailQueue::MaxPackets", UintegerValue (4));
|
||||
Config::SetDefault ("ns3::Queue::MaxPackets", UintegerValue (4));
|
||||
|
||||
NodeContainer n0n1;
|
||||
n0n1.Create (2);
|
||||
|
||||
@@ -278,7 +278,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::DropTailQueue::MaxPackets", UintegerValue (20));
|
||||
Config::SetDefault ("ns3::Queue::MaxPackets", UintegerValue (20));
|
||||
Config::SetDefault ("ns3::TcpSocketBase::Timestamp", BooleanValue (false));
|
||||
|
||||
if (m_writeLogging)
|
||||
|
||||
Reference in New Issue
Block a user