27.6 Queue Monitoring

Queue monitoring refers to the capability of tracking the dynamics of packets at a queue (or other object). A queue monitor tracks packet arrival/departure/drop statistics, and may optionally compute averages of these values. Monitoring may be applied to all packets (aggregate statistics), or per-flow statistics (using a Flow Monitor).

Several classes are used in supporting queue monitoring. When a packet arrives at a link where queue monitoring is enabled, it generally passes through a SnoopQueue object when it arrives and leaves (or is dropped). These objects contain a reference to a QueueMonitor object.

A QueueMonitor is defined as follows (~ns/queue-monitor.cc):

        class QueueMonitor : public TclObject {
         public: 
                QueueMonitor() : bytesInt_(NULL), pktsInt_(NULL), delaySamp_(NULL),
                  size_(0), pkts_(0),
                  parrivals_(0), barrivals_(0),
                  pdepartures_(0), bdepartures_(0),
                  pdrops_(0), bdrops_(0),
                  srcId_(0), dstId_(0), channel_(0) {

                        bind("size_", &size_);
                        bind("pkts_", &pkts_);
                        bind("parrivals_", &parrivals_);
                        bind("barrivals_", &barrivals_);
                        bind("pdepartures_", &pdepartures_);
                        bind("bdepartures_", &bdepartures_);
                        bind("pdrops_", &pdrops_);
                        bind("bdrops_", &bdrops_);
                        bind("off_cmn_", &off_cmn_);
                };

                int size() const { return (size_); }
                int pkts() const { return (pkts_); }
                int parrivals() const { return (parrivals_); }
                int barrivals() const { return (barrivals_); }
                int pdepartures() const { return (pdepartures_); }
                int bdepartures() const { return (bdepartures_); }
                int pdrops() const { return (pdrops_); }
                int bdrops() const { return (bdrops_); }
                void printStats();
                virtual void in(Packet*);
                virtual void out(Packet*);
                virtual void drop(Packet*);
                virtual void edrop(Packet*) { abort(); }; // not here
                virtual int command(int argc, const char*const* argv);
                \ldots

        // packet arrival to a queue
        void QueueMonitor::in(Packet* p)
        {
                hdr_cmn* hdr = (hdr_cmn*)p-\>access(off_cmn_);
                double now = Scheduler::instance().clock();
                int pktsz = hdr-\>size();

                barrivals_ += pktsz;
                parrivals_++;
                size_ += pktsz;
                pkts_++;
                if (bytesInt_)
                        bytesInt_-\>newPoint(now, double(size_));
                if (pktsInt_)
                        pktsInt_-\>newPoint(now, double(pkts_));
                if (delaySamp_)
                        hdr-\>timestamp() = now;
                if (channel_)
                        printStats();
        }

        \ldots \fcn[]{in}, \fcn[]{out}, \fcn[]{drop} are all defined similarly \ldots
It addition to the packet and byte counters, a queue monitor may optionally refer to objects that keep an integral of the queue size over time using Integrator objects, which are defined in Section [*]. The Integrator class provides a simple implementation of integral approximation by discrete sums.

All bound variables beginning with p refer to packet counts, and all variables beginning with b refer to byte counts. The variable size_ records the instantaneous queue size in bytes, and the variable pkts_ records the same value in packets. When a QueueMonitor is configured to include the integral functions (on bytes or packets or both), it computes the approximate integral of the queue size (in bytes) with respect to time over the interval $[t_0, now]$, where $t_0$ is either the start of the simulation or the last time the sum
_
field of the underlying Integrator class was reset.

The QueueMonitor class is not derived from Connector, and is not linked directly into the network topology. Rather, objects of the SnoopQueue class (or its derived classes) are inserted into the network topology, and these objects contain references to an associated queue monitor. Ordinarily, multiple SnoopQueue objects will refer to the same queue monitor. Objects constructed out of these classes are linked in the simulation topology as described above and call QueueMonitor out, in, or drop procedures, depending on the particular type of snoopy queue.

Tom Henderson 2014-12-17