[ns] rsvp patch error in wfq.cc

Alexander Sayenko sayenko at cc.jyu.fi
Tue Sep 6 07:23:10 PDT 2005


Hi

You can use the later version of RSVP that you can find on my website.
http://www.cc.jyu.fi/~sayenko
It contains some bugfixes. However, it will not help with wfq.cc. I have
recently noticed that problem and had an intention to fix it. As a new
version is available, I will mail to the ns-user list.

Sincerely,
Sayenko Alexander
PhD student
Telecommunication laboratory, MIT department
University of Jyvaskyla, Finland


>
>


----------------------------------------------------------------------------
----


>
>
> Hi,
>
> I'm getting the following error compiling rsvp in ns-2.27.
> I'm using fedora core 3 shipped with gcc-3.4, I already applied the
> patch to compile 2.27 with gcc-3.4 and I built it successful without rsvp.
>
> Now I'm trying with rsvp patch. Here is the output of patching
> Did Anybody already use that patch?
> http://www.cse.unsw.edu.au/~mamalik/rsvponns2.html
> <http://www.cse.unsw.edu.au/%7Emamalik/rsvponns2.html>
>
> #patch -p1 < ns-2.27-rsvp.patch1
>
> patching file common/packet.h
> Hunk #1 succeeded at 160 with fuzz 2 (offset 7 lines).
> Hunk #2 succeeded at 252 with fuzz 2 (offset 6 lines).
> patching file FILES
> Hunk #1 succeeded at 1020 (offset 58 lines).
> Hunk #2 succeeded at 1254 (offset 34 lines).
> Hunk #3 succeeded at 1439 (offset 70 lines).
> patching file Makefile.in
> patching file makefile.vc
> Hunk #1 succeeded at 247 (offset -13 lines).
> Hunk #2 succeeded at 372 (offset -6 lines).
> patching file rsvp/rsvp.cc
> patching file rsvp/rsvp.h
> patching file rsvp/rsvp-link.cc
> patching file rsvp/rsvp-link.h
> patching file rsvp/rsvp-messages.cc
> patching file rsvp/rsvp-messages.h
> patching file rsvp/rsvp-objects.cc
> patching file rsvp/rsvp-objects.h
> patching file rsvp/wfq.cc
> patching file rsvp/wfq.h
> patching file tcl/ex/rsvp/rsvp_conf.tcl
> patching file tcl/ex/rsvp/rsvp_distinct.tcl
> patching file tcl/ex/rsvp/rsvp_large.tcl
> patching file tcl/ex/rsvp/rsvp_merge.tcl
> patching file tcl/lib/ns-lib.tcl
> patching file tcl/lib/ns-packet.tcl
> patching file tcl/lib/ns-rsvp.tcl
>
>
> And here is the error in make.
>
> g++ -c  -DTCP_DELAY_BIND_ALL -DNO_TK -DTCLCL_CLASSINSTVAR  -DNDEBUG
> -DLINUX_TCP_HEADER -DUSE_SHM -DHAVE_LIBTCLCL -DHAVE_TCLCL_H
> -DHAVE_LIBOTCL1_8 -DHAVE_OTCL_H -DHAVE_LIBTK8_4 -DHAVE_TK_H
> -DHAVE_LIBTCL8_4 -DHAVE_TCL_H  -DHAVE_CONFIG_H -DNS_DIFFUSION
> -DSMAC_NO_SYNC -DCPP_NAMESPACE=std -DUSE_SINGLE_ADDRESS_SPACE -Drng_test
> -I. -I/usr/local/ns-allinone-2.27/tclcl-1.15
> -I/usr/local/ns-allinone-2.27/otcl-1.8
> -I/usr/local/ns-allinone-2.27/include
> -I/usr/local/ns-allinone-2.27/include -I/usr/include/pcap -I./tcp
> -I./sctp -I./common -I./link -I./queue -I./adc -I./apps -I./mac
> -I./mobile -I./trace -I./routing -I./tools -I./classifier -I./mcast
> -I./diffusion3/lib/main -I./diffusion3/lib -I./diffusion3/lib/nr
> -I./diffusion3/ns -I./diffusion3/filter_core -I./asim/ -I./qs -o
> rsvp/wfq.o rsvp/wfq.cc
> rsvp/wfq.cc: In constructor `Hashtable::Hashtable(int)':
> rsvp/wfq.cc:479: error: array bound forbidden after parenthesized type-id
> rsvp/wfq.cc:479: note: try removing the parentheses around the type-id
> make: ** [rsvp/wfq.o] Erro 1
> Ns make failed!
> See http://www.isi.edu/nsnam/ns/ns-problems.html for problems
>
>
>
> Ah, my wfq.cc is attached.
>
> thank you
> pedro burjack
>
>
>
>
>
>
>


----------------------------------------------------------------------------
----


> /*
>  * Copyright (c) 1998 The University of Bonn
>  * All rights reserved.
>  *
>  * Permission to use and copy this software in source and binary forms
>  * is hereby granted, provided that the above copyright notice, this
>  * paragraph and the following disclaimer are retained in any copies
>  * of any part of this software and that the University of Bonn is
>  * acknowledged in all documentation pertaining to any such copy
>  * or derivative work. The name of the University of Bonn may not
>  * be used to endorse or promote products derived from this software
>  * without specific prior written permission.
>  *
>  * THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>  * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF
>  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
>  * THE UNIVERSITY OF BONN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY,
>  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF
>  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
>  * SOFTWARE.
>  */
>
> #include "wfq.h"
>
>
> static class WFQClassCl : public TclClass {
> public:
>   WFQClassCl() : TclClass("WFQClass") {}
>   TclObject* create(int, const char*const*) {
>     return (new WFQClass);
>   }
> } class_WFQClass;
>
>
> WFQClass::WFQClass() : next_(0), bw_(0), next_time_(-1), last_time_(-1) {
>   //bind("off_cmn_", &off_cmn_);
>   bind("limit_", &qlim_);
>   bind_bw("bw_", &bw_);
>   q_ = new PacketQueue;
>   size_ = 0;
> }
>
>
> /* Inserts a packet into the queue associated with the WFQClass and
>    calculates the new size (in bytes). */
> void WFQClass::enque(Packet *p) {
>   //hdr_cmn *hdr = (hdr_cmn*)p->access(off_cmn_);
>   hdr_cmn *hdr = hdr_cmn::access(p) ;
>   q_->enque(p);
>   size_ += hdr->size();
> }
>
>
> /* Removes a packet from the queue associated with the WFQClass
>    and calculates the new size (in bytes). */
> Packet *WFQClass::deque() {
>   Packet *p = q_->deque();
>   //hdr_cmn *hdr = (hdr_cmn*)p->access(off_cmn_);
>   hdr_cmn *hdr = hdr_cmn::access(p) ;
>   size_ -= hdr->size();
>   return p;
> }
>
>
> /*
>  * The function 'calculate_next_time()' is the 'heart' both of the
>  * WFQ and WF2Q algorithms. It calculates the time at which the next
>  * packet for the queue would complete service in the corresponding
>  * GPS system.
>  */
> void WFQClass::calculate_next_time() {
>   Packet *np = q_->head();
>   //hdr_cmn *hdr = (hdr_cmn*)np->access(off_cmn_);
>   hdr_cmn *hdr = hdr_cmn::access(np) ;
>   last_time_ = next_time_;
>   /* For packet i that arrives in a queue, the completion time
>    * c_time(i) is:
>    * c_time(i) = max {(time() + size(i)/rate) ; (c_time(i-1) +
size(i)/rate)}
>    * Note that the size of a packet is measured in bytes while the
bandwidth
>    * is measured in bits per second, hence the 'size()*8' calculation in
>    * the formula below.
>    */
>   if (Scheduler::instance().clock() > next_time_) {
>     next_time_ = Scheduler::instance().clock() + hdr->size()*8 / bw_; }
>   else {
>     next_time_ = next_time_ + hdr->size()*8 / bw_;
>   }
> }
>
>
> /*
>  * There are no commands for the class WFQClass yet. This might
>  * change later.
>  */
> int WFQClass::command(int argc, const char*const* argv) {
>   return (Queue::command(argc, argv));
> }
>
>
> static class WFQCl : public TclClass {
> public:
>   WFQCl() : TclClass("Queue/WFQ") {}
>   TclObject* create(int, const char*const*) {
>     return (new WFQ);
>   }
> } class_WFQ;
>
>
> WFQ::WFQ() : queue_list_(0) {
>   // int i; - unused
>   //bind("off_ip_", &off_ip_);
>   //bind("off_cmn_", &off_cmn_);
>   bind_bool("wf2q_", &wf2q_);
>   bind_bool("best_effort_", &best_effort_);
>   bind_bool("borrow_", &borrow_);
>   bind_bool("prio_", &prio_);
>   bind("num_classes_", &num_classes_);
>   bind("num_flows_", &num_flows_);
>   bind("num_drops_", &num_drops_);
>   bind("size_drops_", &size_drops_);
>   hash = new Hashtable(HASHBUCKETS);
> }
>
>
> /*
>  * New classes can be added to (or removed from) a WFQ link with
>  * 'add WFQClass' (or 'remove WFQClass'). Flows can be assigned to
>  * a class (or the assignment can be deleted) with 'bind WFQClass
<flowid>'
>  * (or 'unbind <flowid>').
>  */
> int WFQ::command(int argc, const char*const* argv) {
>   Tcl& tcl = Tcl::instance();
>   if (argc == 3) {
>     // add WFQClass
>     if (strcmp(argv[1], "add") == 0) {
>       WFQClass *cl = (WFQClass*)TclObject::lookup(argv[2]);
>       if (cl == NULL) {
> tcl.resultf("WFQ: no class object %s", argv[2]);
> return (TCL_ERROR);
>       }
>       insert(cl);
>       num_classes_++;
>       return (TCL_OK);
>     }
>     // remove WFQClass
>     if (strcmp(argv[1], "remove") == 0) {
>       WFQClass *cl = (WFQClass*)TclObject::lookup(argv[2]);
>       if (cl == NULL) {
> tcl.resultf("WFQ: no class object %s", argv[2]);
> return (TCL_ERROR);
>       }
>       WFQClass *search = queue_list_;
>       if (queue_list_ == NULL) {
> tcl.resultf("WFQ: no class object %s found in WFQ link", argv[2]);
> return (TCL_ERROR);
>       }
>       if (queue_list_ == cl) {
> queue_list_ = queue_list_->next_;
>       } else {
> while ((search->next_ != NULL) && (search->next_ != cl)) {
>   search = search->next_;
> }
> if (search->next_ == NULL) {
>   tcl.resultf("WFQ: no class object %s found in WFQ link", argv[2]);
>   return (TCL_ERROR);
> }
> search->next_ = search->next_->next_;
>       }
>       num_classes_--;
>       return (TCL_OK);
>     }
>     // getclass <flowid>
>     if (strcmp(argv[1], "getclass") == 0) {
>       WFQClass *cl;
>       int fid = atoi(argv[2]);
>       if ((cl = (WFQClass *)hash->lookup(fid)) == NULL) {
> tcl.resultf("");
>       } else {
> tcl.resultf("%s", cl->name());
>       }
>       return (TCL_OK);
>     }
>   }
>   if ((argc == 4) || (argc == 5)) {
>     // bind WFQClass <priority>   or   bind WFQClass <src id> <flowid>
>     if (strcmp(argv[1], "bind") == 0) {
>       WFQClass *cl = (WFQClass*)TclObject::lookup(argv[2]);
>       if (cl == NULL) {
> tcl.resultf("WFQ: no class object %s", argv[2]);
> return (TCL_ERROR);
>       }
>       WFQClass *search = queue_list_;
>       while ((search != NULL) && (search != cl)) {
> search = search->next_;
>       }
>       if (search == NULL) {
> tcl.resultf("WFQ: no class object %s found in WFQ link", argv[2]);
> return (TCL_ERROR);
>       }
>       int fid = -1;
>       if ((prio_) && (argc == 4)) {
> fid = atoi(argv[3]);
>       }
>       if ((!prio_) && (argc == 5)) {
> fid = (atoi(argv[3]) + 1) * FLOWNUM + atoi(argv[4]);
>       }
>       if (fid == -1) {
> tcl.resultf("WFQ: Wrong number of arguments for bind");
> return (TCL_ERROR);
>       }
>       hash->insert(cl, fid);
>       num_flows_++;
>       return(TCL_OK);
>     }
>   }
>   if ((argc == 3) || (argc == 4)) {
>     // unbind <flowid>   or   unbind <src id> <flowid>
>     if (strcmp(argv[1], "unbind") == 0) {
>       int fid = -1;
>       if ((prio_) && (argc == 3)) {
> fid = atoi(argv[2]);
>       }
>       if ((!prio_) && (argc == 4)) {
> fid = (atoi(argv[2]) + 1) * FLOWNUM + atoi(argv[3]);
>       }
>       if (fid == -1) {
> tcl.resultf("WFQ: Wrong number of arguments for unbind");
> return (TCL_ERROR);
>       }
>       if (hash->lookup(fid) == NULL) {
> tcl.resultf("%s WFQ: No class assigned to flow %d", name(), fid);
> return (TCL_ERROR);
>       }
>       hash->remove(fid);
>       num_flows_--;
>       return(TCL_OK);
>     }
>   }
>   return (Queue::command(argc, argv));
> }
>
>
> int WFQ::length() {
>   WFQClass *s = queue_list_;
>   int l;
>   l = 0;
>   while (s != NULL) {
>     l += s->length();
>     s = s->next_;
>   }
>   return l;
> }
>
>
> void WFQ::enque(Packet* p)
> {
>   int num;
>   WFQClass *cl; // , *next; - next is unused
>   int be;
>   Tcl& tcl = Tcl::instance();
>   // hdr_ip *hdr = (hdr_ip*)p->access(off_ip_);
>   hdr_ip *hdr = hdr_ip::access(p) ;
>   // Check if a class has been assigned to this flow/priority:
>   if (prio_) {
>     num = hdr->prio();
>     cl = (WFQClass *)hash->lookup(num);
>     if ((be = (cl == NULL))) {
>       if (best_effort_) {
> cl = (WFQClass *)hash->lookup(0);
>       } else {
> tcl.evalf("%s WFQ: unknown priority %u",name(), num);
>       }
>     }
>   } else {
>     // num = ((hdr->src() >> Address::instance().NodeShift_[1]) + 1) *
FLOWNUM +
>     num = ( hdr->saddr() + 1 ) * FLOWNUM + // SM
>       hdr->flowid();
>     cl = (WFQClass *)hash->lookup(num);
>     if (cl == NULL) {
>       num = hdr->flowid();
>       cl = (WFQClass *)hash->lookup(num);
>     }
>     if ((be = (cl == NULL))) {
>       if (best_effort_) {
> cl = (WFQClass *)hash->lookup(0);
>       } else {
> tcl.evalf("%s WFQ: unknown flow %u",name(), num);
>       }
>     }
>   }
>   /* Is the queue full? Drop the packet, or if best effort and borrow
>      mode is enabled and it is not already in the best-effort class,
>      try to insert it into the best-effort class. */
>   //hdr_cmn *hdrc = (hdr_cmn*)p->access(off_cmn_);
>   hdr_cmn *hdrc = hdr_cmn::access(p) ;
>   if (cl->length() + hdrc->size() > cl->limit()) {
>     if (best_effort_ && borrow_ && (num > 0)) {
>       cl = (WFQClass*)hash->lookup(0);
>       if (cl->length() + hdrc->size() > cl->limit()) {
> drop(p);
> if (!be) {
>   num_drops_++;
>   size_drops_ += hdrc->size();
> }
>       } else {
> cl->enque(p);
> // Check if the queue was empty. In that case, calculate
> // the GPS completion time for the new packet.
> if (cl->get_next_time() == -1) {
>   cl->calculate_next_time();
> }
> // Sort the queue list
> reinsert(cl);
>       }
>     } else {
>       drop(p);
>       if ((!be) && (num > 0)) {
>   num_drops_++;
> size_drops_ += hdrc->size();
>       }
>     }
>   } else {
>     cl->enque(p);
>     // Check if the queue was empty. In that case, calculate
>     // the GPS completion time for the new packet.
>     if (cl->get_next_time() == -1) {
>       cl->calculate_next_time();
>     }
>     // Sort the queue list
>     reinsert(cl);
>   }
> }
>
>
> int WFQ::greater(double t1, double t2) {
>   if (t2 == -1) return 0;
>   if (t1 == -1) return 1;
>   if (t1 > t2) return 1;
>   return 0;
> }
>
>
> /*
>  * The function 'WFQ::insert()' inserts a WFQClass into the sorted
>  * queue list
>  */
> void WFQ::insert(WFQClass *element) {
>  if ((queue_list_ == NULL) ||
>      greater(queue_list_->get_next_time(), element->get_next_time())) {
>     element->next_ = queue_list_;
>     queue_list_ = element;
>   } else {
>     WFQClass *search = queue_list_;
>     WFQClass *next = search->next_;
>     while ((next != NULL) &&
>    greater(element->get_next_time(), next->get_next_time())) {
>       search = search->next_;
>       next = next->next_;
>     }
>     search->next_ = element;
>     element->next_ = next;
>   }
> }
>
>
> /*
>  * The function 'WFQ::reinsert' removes an element for the sorted
>  * queue list, then inserts it in the right place with the 'WFQ::insert()'
>  * function.
>  */
> void WFQ::reinsert(WFQClass *element) {
>   WFQClass *search;
>   if (queue_list_ == element) {
>     queue_list_ = queue_list_->next_;
>     insert(element);
>   } else {
>     search = queue_list_;
>     while (search->next_ != element) {
>       search = search->next_;
>     }
>     search->next_ = element->next_;
>     insert(element);
>   }
> }
>
>
> /*
>  * The function 'WFQ::deque()' has to decide which queue is to be
>  * served next. In the original WFQ algorithm, this is always the queue
>  * with the lowest completion time for the next packet. In WF2Q, it is
>  * the queue with the lowest completion time of all queues that would
>  * already be served in the GPS system (or if no queues would be served
>  * at the moment, the queue with the lowest completion time is chosen).
>  */
> Packet* WFQ::deque()
> {
>   Packet *p; //, *np; - np is unused
>   // Are we using the WFQ or the WF2Q algorithm?
>   if (wf2q_ == 0) {
>     // ***** WFQ *****
>     WFQClass *head;
>     // Are there any packets in the queue?
>     if ((queue_list_ == NULL) || (queue_list_->get_next_time() == -1)) {
>       return NULL;
>     }
>     // Take the next packet from the first queue in the list
>     p = queue_list_->deque();
>     // Determine the next completion time: Either -1 if the queue is
>     // empty now, or the result of the 'calculate_next_time' function.
>     // Then insert the queue in the right place in the sorted queue list.
>     if (queue_list_->length() == 0) {
>       queue_list_->set_next_time(-1);
>       if ((queue_list_->next_ != NULL) &&
>   (queue_list_->next_->get_next_time() != -1)) {
> head = queue_list_;
> queue_list_ = queue_list_->next_;
> insert(head);
>       }
>     } else {
>       queue_list_->calculate_next_time();
>       if ((queue_list_->next_ != NULL) &&
>   (queue_list_->next_->get_next_time() != -1) &&
>   (queue_list_->next_->get_next_time() < queue_list_->get_next_time())) {
> head = queue_list_;
> queue_list_ = queue_list_->next_;
> insert(head);
>       }
>     }
>     return p;
>   } else {
>     // ***** WF2Q *****
>     WFQClass *search, *element;
>     // Are there any packets in the queue?
>     if ((queue_list_ == NULL) || (queue_list_->get_next_time() == -1)) {
>       return NULL;
>     }
>     // Has the first queue in the list already started service in the
>     // GPS system?
>     if (Scheduler::instance().clock() > queue_list_->get_last_time()) {
>       element = queue_list_;
>       queue_list_ = queue_list_->next_;
>     } else {
>       // If not, search for the first queue in the list which has
>       // started service in the GPS system
>       search = queue_list_;
>       while ((search->next_ != NULL) &&
>      (Scheduler::instance().clock() <= search->next_->get_last_time()) &&
>      (search->next_->get_next_time() != -1)) {
> search = search->next_;
>       }
>       // If none is found, simply choose the first queue.
>       if ((search->next_ == NULL) || (search->next_->get_next_time()
== -1)) {
> element = queue_list_;
> queue_list_ = queue_list_->next_;
>       } else {
> element = search->next_;
> search->next_ = search->next_->next_;
>       }
>     }
>     // Take the first packet from the queue, recalculate the completion
>     // time (either -1 if the queue is empty now, or the result of the
>     // 'calculate_next_time()' function), then insert the element into
>     // the right place in the sorted queue list.
>     p = element->deque();
>     if (element->length() == 0) {
>       element->set_last_time(-1);
>       element->set_next_time(-1);
>     } else {
>       element->calculate_next_time();
>     }
>     insert(element);
>     return p;
>   }
> }
>
>
> Hashtable::Hashtable(int buckets) {
>   buckets_ = buckets;
>   table_ = new (node *)[buckets];
>   int i;
>   for (i = 0; i < buckets; i++) {
>     table_[i] = NULL;
>   }
> }
>
>
> void Hashtable::insert(TclObject *obj, int value) {
>   if (lookup(value) == NULL) {
>     int bucket = value % buckets_;
>     node *n, *s;
>     n = new node;
>     n->obj = obj;
>     n->value = value;
>     n->next = NULL;
>     if (table_[bucket] == NULL) {
>       table_[bucket] = n;
>     } else {
>       if (value < table_[bucket]->value) {
> n->next = table_[bucket];
> table_[bucket] = n;
>       } else {
> s = table_[bucket];
> /* The elements are sorted in ascending order. Since it can be assumed
>    that lookups will occur much more often than inserts, this can
>    increase the performance considerably. */
> while ((s->next != NULL) && (s->next->value < value)) {
>   s = s->next;
> }
> n->next = s->next;
> s->next = n;
>       }
>     }
>   }
> }
>
>
> void Hashtable::remove(int value) {
>   int bucket = value % buckets_;
>   node *temp;
>   node *s = table_[bucket];
>   if (s != NULL) {
>     if (s->value == value) {
>       table_[bucket] = s->next;
>       delete s;
>     } else {
>       while ((s->next != NULL) && (s->next->value < value)) {
> s = s->next;
>       }
>       if ((s->next != NULL) && (s->next->value == value)) {
> temp = s->next;
> s->next = temp->next;
> delete temp;
>       }
>     }
>   }
> }
>
>
>
> TclObject *Hashtable::lookup(int value) {
>   int bucket = value % buckets_;
>   node *s = table_[bucket];
>   while ((s != NULL) && (s->value != value)) {
>     s = s->next;
>   }
>   if (s != NULL) {
>     return s->obj;
>   } else {
>     return NULL;
>   }
> }
>
>
>
>
>
>
>


----------------------------------------------------------------------------
----


No virus found in this incoming message.
Checked by AVG Anti-Virus.
Version: 7.0.344 / Virus Database: 267.10.18/90 - Release Date: 05.09.2005



More information about the Ns-users mailing list