00001 #include <assert.h>
00002
00003 #include <rtqueue.h>
00004 #include <cmu-trace.h>
00005
00006 #define CURRENT_TIME Scheduler::instance().clock()
00007 #define DEBUG
00008
00009
00010
00011
00012 rtqueue::rtqueue()
00013 {
00014 head_ = tail_ = 0;
00015 len_ = 0;
00016
00017 limit_ = RTQ_MAX_LEN;
00018 timeout_ = RTQ_TIMEOUT;
00019 }
00020
00021 void
00022 rtqueue::enque(Packet *p)
00023 {
00024 struct hdr_cmn *ch = HDR_CMN(p);
00025
00026 p->next_ = 0;
00027 ch->ts_ = CURRENT_TIME + timeout_;
00028
00029 if (len_ == limit_) {
00030 Packet *p0 = remove_head();
00031
00032 assert(p0);
00033
00034 if(HDR_CMN(p0)->ts_ > CURRENT_TIME) {
00035 drop(p0, DROP_RTR_QFULL);
00036 }
00037 else {
00038 drop(p0, DROP_RTR_QTIMEOUT);
00039 }
00040 }
00041 if(head_ == 0) {
00042 head_ = tail_ = p;
00043 }
00044 else {
00045 tail_->next_ = p;
00046 tail_ = p;
00047 }
00048 len_++;
00049 #ifdef DEBUG
00050 verifyQueue();
00051 #endif
00052 }
00053
00054
00055 Packet*
00056 rtqueue::deque()
00057 {
00058 Packet *p;
00059
00060
00061
00062
00063 purge();
00064
00065 p = remove_head();
00066 #ifdef DEBUG
00067 verifyQueue();
00068 #endif
00069 return p;
00070 }
00071
00072
00073 Packet*
00074 rtqueue::deque(nsaddr_t dst)
00075 {
00076 Packet *p, *prev;
00077
00078
00079
00080
00081 purge();
00082
00083 findPacketWithDst(dst, p, prev);
00084 assert(p == 0 || (p == head_ && prev == 0) || (prev->next_ == p));
00085
00086 if(p == 0) return 0;
00087
00088 if (p == head_) {
00089 p = remove_head();
00090 }
00091 else if (p == tail_) {
00092 prev->next_ = 0;
00093 tail_ = prev;
00094 len_--;
00095 }
00096 else {
00097 prev->next_ = p->next_;
00098 len_--;
00099 }
00100
00101 #ifdef DEBUG
00102 verifyQueue();
00103 #endif
00104 return p;
00105 }
00106
00107 char
00108 rtqueue::find(nsaddr_t dst)
00109 {
00110 Packet *p, *prev;
00111 findPacketWithDst(dst, p, prev);
00112 if (0 == p)
00113 return 0;
00114 else
00115 return 1;
00116 }
00117
00118
00119
00120
00121
00122
00123
00124 Packet*
00125 rtqueue::remove_head()
00126 {
00127 Packet *p = head_;
00128
00129 if(head_ == tail_) {
00130 head_ = tail_ = 0;
00131 }
00132 else {
00133 head_ = head_->next_;
00134 }
00135
00136 if(p) len_--;
00137
00138 return p;
00139 }
00140
00141 void
00142 rtqueue::purge()
00143 {
00144 Packet *p;
00145
00146 while((p = head_) && HDR_CMN(p)->ts_ < CURRENT_TIME) {
00147 Packet *temp = remove_head();
00148 assert(p == temp);
00149 drop(p, DROP_RTR_QTIMEOUT);
00150 }
00151 }
00152
00153 void
00154 rtqueue::findPacketWithDst(nsaddr_t dst, Packet*& p, Packet*& prev)
00155 {
00156 p = prev = 0;
00157
00158 for(p = head_; p; p = p->next_) {
00159
00160 if(HDR_IP(p)->daddr() == dst) {
00161 return;
00162 }
00163 prev = p;
00164 }
00165
00166 if(p == 0) prev = 0;
00167 }
00168
00169
00170 void
00171 rtqueue::verifyQueue()
00172 {
00173 Packet *p, *prev = 0;
00174 int cnt = 0;
00175
00176 for(p = head_; p; p = p->next_) {
00177 cnt++;
00178 prev = p;
00179 }
00180 assert(cnt == len_);
00181 assert(prev == tail_);
00182 }
00183
00184