priqueue.cc

Go to the documentation of this file.
00001 /* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
00002 /*
00003  * Copyright (c) 1997 Regents of the University of California.
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  * 3. All advertising materials mentioning features or use of this software
00015  *    must display the following acknowledgement:
00016  *  This product includes software developed by the Computer Systems
00017  *  Engineering Group at Lawrence Berkeley Laboratory.
00018  * 4. Neither the name of the University nor of the Laboratory may be used
00019  *    to endorse or promote products derived from this software without
00020  *    specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00023  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00026  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00027  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00028  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00031  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00032  * SUCH DAMAGE.
00033  */
00034 /* Ported from CMU/Monarch's code, nov'98 -Padma.*/
00035 
00036 /* -*- c++ -*-
00037    priqueue.cc
00038    
00039    A simple priority queue with a remove packet function
00040    $Id: priqueue.cc,v 1.7 2004/10/07 17:56:03 haldar Exp $
00041    */
00042 
00043 #include <object.h>
00044 #include <queue.h>
00045 #include <drop-tail.h>
00046 #include <packet.h>
00047 #include <cmu-trace.h>
00048 
00049 #include "priqueue.h"
00050 
00051 typedef int (*PacketFilter)(Packet *, void *);
00052 
00053 PriQueue_List PriQueue::prhead = { 0 };
00054 
00055 static class PriQueueClass : public TclClass {
00056 public:
00057   PriQueueClass() : TclClass("Queue/DropTail/PriQueue") {}
00058   TclObject* create(int, const char*const*) {
00059     return (new PriQueue);
00060   }
00061 } class_PriQueue;
00062 
00063 
00064 PriQueue::PriQueue() : DropTail()
00065 {
00066         bind("Prefer_Routing_Protocols", &Prefer_Routing_Protocols);
00067     LIST_INSERT_HEAD(&prhead, this, link);
00068 }
00069 
00070 int
00071 PriQueue::command(int argc, const char*const* argv)
00072 {
00073   if (argc == 2 && strcasecmp(argv[1], "reset") == 0)
00074     {
00075       Terminate();
00076       //FALL-THROUGH to give parents a chance to reset
00077     }
00078   return DropTail::command(argc, argv);
00079 }
00080 
00081 void
00082 PriQueue::recv(Packet *p, Handler *h)
00083 {
00084         struct hdr_cmn *ch = HDR_CMN(p);
00085 
00086         if(Prefer_Routing_Protocols) {
00087 
00088                 switch(ch->ptype()) {
00089         case PT_DSR:
00090         case PT_MESSAGE:
00091                 case PT_TORA:
00092                 case PT_AODV:
00093                         recvHighPriority(p, h);
00094                         break;
00095 
00096                 default:
00097                         Queue::recv(p, h);
00098                 }
00099         }
00100         else {
00101                 Queue::recv(p, h);
00102         }
00103 }
00104 
00105 
00106 void 
00107 PriQueue::recvHighPriority(Packet *p, Handler *)
00108   // insert packet at front of queue
00109 {
00110     q_->enqueHead(p);
00111     if (q_->length() >= qlim_)
00112     {
00113       Packet *to_drop = q_->lookup(q_->length()-1);
00114       q_->remove(to_drop);
00115       drop(to_drop);
00116     }
00117   
00118   if (!blocked_) {
00119     /*
00120      * We're not blocked.  Get a packet and send it on.
00121      * We perform an extra check because the queue
00122      * might drop the packet even if it was
00123      * previously empty!  (e.g., RED can do this.)
00124      */
00125     p = deque();
00126     if (p != 0) {
00127       blocked_ = 1;
00128       target_->recv(p, &qh_);
00129     }
00130   } 
00131 }
00132  
00133 void 
00134 PriQueue::filter(PacketFilter filter, void * data)
00135   // apply filter to each packet in queue, 
00136   // - if filter returns 0 leave packet in queue
00137   // - if filter returns 1 remove packet from queue
00138 {
00139   int i = 0;
00140   while (i < q_->length())
00141     {
00142       Packet *p = q_->lookup(i);
00143       if (filter(p,data))
00144     {
00145       q_->remove(p); // decrements q len
00146     }
00147       else i++;
00148     }
00149 }
00150 
00151 Packet*
00152 PriQueue::filter(nsaddr_t id)
00153 {
00154     Packet *p = 0;
00155     Packet *pp = 0;
00156     struct hdr_cmn *ch;
00157 
00158     for(p = q_->head(); p; p = p->next_) {
00159         ch = HDR_CMN(p);
00160         if(ch->next_hop() == id)
00161             break;
00162         pp = p;
00163     }
00164 
00165     /*
00166      * Deque Packet
00167      */
00168     if(p) {
00169         if(pp == 0)
00170             q_->remove(p);
00171         else
00172             q_->remove(p, pp);
00173     }
00174     return p;
00175 }
00176 
00177 /*
00178  * Called at the end of the simulation to purge the IFQ.
00179  */
00180 void
00181 PriQueue::Terminate()
00182 {
00183     Packet *p;
00184     while((p = deque())) {
00185         drop(p, DROP_END_OF_SIMULATION);
00186         //drop(p);
00187         
00188     }
00189 }
00190 
00191 
00192 
00193 

Generated on Tue Mar 6 16:47:49 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6