00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef lint
00036 static const char rcsid[] =
00037 "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/queue/drop-tail.cc,v 1.17 2004/10/28 23:35:37 haldar Exp $ (LBL)";
00038 #endif
00039
00040 #include "drop-tail.h"
00041
00042 static class DropTailClass : public TclClass {
00043 public:
00044 DropTailClass() : TclClass("Queue/DropTail") {}
00045 TclObject* create(int, const char*const*) {
00046 return (new DropTail);
00047 }
00048 } class_drop_tail;
00049
00050 void DropTail::reset()
00051 {
00052 Queue::reset();
00053 }
00054
00055 int
00056 DropTail::command(int argc, const char*const* argv)
00057 {
00058 if (argc==2) {
00059 if (strcmp(argv[1], "printstats") == 0) {
00060 print_summarystats();
00061 return (TCL_OK);
00062 }
00063 if (strcmp(argv[1], "shrink-queue") == 0) {
00064 shrink_queue();
00065 return (TCL_OK);
00066 }
00067 }
00068 if (argc == 3) {
00069 if (!strcmp(argv[1], "packetqueue-attach")) {
00070 delete q_;
00071 if (!(q_ = (PacketQueue*) TclObject::lookup(argv[2])))
00072 return (TCL_ERROR);
00073 else {
00074 pq_ = q_;
00075 return (TCL_OK);
00076 }
00077 }
00078 }
00079 return Queue::command(argc, argv);
00080 }
00081
00082
00083
00084
00085 void DropTail::enque(Packet* p)
00086 {
00087 if (summarystats) {
00088 Queue::updateStats(qib_?q_->byteLength():q_->length());
00089 }
00090
00091 int qlimBytes = qlim_ * mean_pktsize_;
00092 if ((!qib_ && (q_->length() + 1) >= qlim_) ||
00093 (qib_ && (q_->byteLength() + hdr_cmn::access(p)->size()) >= qlimBytes)){
00094
00095 if (drop_front_) {
00096 q_->enque(p);
00097 Packet *pp = q_->deque();
00098 drop(pp);
00099 } else {
00100 drop(p);
00101 }
00102 } else {
00103 q_->enque(p);
00104 }
00105 }
00106
00107
00108 void DropTail::shrink_queue()
00109 {
00110 int qlimBytes = qlim_ * mean_pktsize_;
00111 if (debug_)
00112 printf("shrink-queue: time %5.2f qlen %d, qlim %d\n",
00113 Scheduler::instance().clock(),
00114 q_->length(), qlim_);
00115 while ((!qib_ && q_->length() > qlim_) ||
00116 (qib_ && q_->byteLength() > qlimBytes)) {
00117 if (drop_front_) {
00118 Packet *pp = q_->deque();
00119 drop(pp);
00120 } else {
00121 Packet *pp = q_->tail();
00122 q_->remove(pp);
00123 drop(pp);
00124 }
00125 }
00126 }
00127
00128 Packet* DropTail::deque()
00129 {
00130 if (summarystats && &Scheduler::instance() != NULL) {
00131 Queue::updateStats(qib_?q_->byteLength():q_->length());
00132 }
00133 return q_->deque();
00134 }
00135
00136 void DropTail::print_summarystats()
00137 {
00138
00139 printf("True average queue: %5.3f", true_ave_);
00140 if (qib_)
00141 printf(" (in bytes)");
00142 printf(" time: %5.3f\n", total_time_);
00143 }