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/queue.cc,v 1.27 2003/01/28 23:31:03 sfloyd Exp $ (LBL)";
00038 #endif
00039
00040 #include "queue.h"
00041 #include <math.h>
00042 #include <stdio.h>
00043
00044 void PacketQueue::remove(Packet* target)
00045 {
00046 for (Packet *pp= 0, *p= head_; p; pp= p, p= p->next_) {
00047 if (p == target) {
00048 if (!pp) deque();
00049 else {
00050 if (p == tail_)
00051 tail_= pp;
00052 pp->next_= p->next_;
00053 --len_;
00054 bytes_ -= hdr_cmn::access(p)->size();
00055 }
00056 return;
00057 }
00058 }
00059 fprintf(stderr, "PacketQueue:: remove() couldn't find target\n");
00060 abort();
00061 }
00062
00063
00064
00065
00066
00067 void PacketQueue::remove(Packet* pkt, Packet *prev)
00068 {
00069 if (pkt) {
00070 if (head_ == pkt)
00071 PacketQueue::deque();
00072 else {
00073 prev->next_ = pkt->next_;
00074 if (tail_ == pkt)
00075 tail_ = prev;
00076 --len_;
00077 bytes_ -= hdr_cmn::access(pkt)->size();
00078 }
00079 }
00080 return;
00081 }
00082
00083 void QueueHandler::handle(Event*)
00084 {
00085 queue_.resume();
00086 }
00087
00088 Queue::~Queue() {
00089 }
00090
00091 Queue::Queue() : Connector(), blocked_(0), unblock_on_resume_(1), qh_(*this),
00092 pq_(0), last_change_(0),
00093 old_util_(0)
00094 {
00095 bind("limit_", &qlim_);
00096 bind("util_weight_", &util_weight_);
00097 bind_bool("blocked_", &blocked_);
00098 bind_bool("unblock_on_resume_", &unblock_on_resume_);
00099 }
00100
00101 void Queue::recv(Packet* p, Handler*)
00102 {
00103 double now = Scheduler::instance().clock();
00104 enque(p);
00105 if (!blocked_) {
00106
00107
00108
00109
00110
00111
00112 p = deque();
00113 if (p != 0) {
00114 utilUpdate(last_change_, now, blocked_);
00115 last_change_ = now;
00116 blocked_ = 1;
00117 target_->recv(p, &qh_);
00118 }
00119 }
00120 }
00121
00122 void Queue::utilUpdate(double int_begin, double int_end, int link_state) {
00123 double decay;
00124
00125 decay = exp(-util_weight_ * (int_end - int_begin));
00126 old_util_ = link_state + (old_util_ - link_state) * decay;
00127
00128 }
00129
00130 double Queue::utilization(void)
00131 {
00132 double now = Scheduler::instance().clock();
00133
00134 utilUpdate(last_change_, now, blocked_);
00135 last_change_ = now;
00136
00137 return old_util_;
00138
00139 }
00140
00141 void Queue::updateStats(int queuesize)
00142 {
00143 double now = Scheduler::instance().clock();
00144 double newtime = now - total_time_;
00145 if (newtime > 0.0) {
00146 double oldave = true_ave_;
00147 double oldtime = total_time_;
00148 double newtime = now - total_time_;
00149 true_ave_ = (oldtime * oldave + newtime * queuesize) /now;
00150 total_time_ = now;
00151 }
00152 }
00153
00154 void Queue::resume()
00155 {
00156 double now = Scheduler::instance().clock();
00157 Packet* p = deque();
00158 if (p != 0) {
00159 target_->recv(p, &qh_);
00160 } else {
00161 if (unblock_on_resume_) {
00162 utilUpdate(last_change_, now, blocked_);
00163 last_change_ = now;
00164 blocked_ = 0;
00165 }
00166 else {
00167 utilUpdate(last_change_, now, blocked_);
00168 last_change_ = now;
00169 blocked_ = 1;
00170 }
00171 }
00172 }
00173
00174 void Queue::reset()
00175 {
00176 Packet* p;
00177 total_time_ = 0.0;
00178 true_ave_ = 0.0;
00179 while ((p = deque()) != 0)
00180 drop(p);
00181 }