Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

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.5 2003/02/21 00:40:22 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 Apr 20 12:14:27 2004 for NS2.26SourcesOriginal by doxygen 1.3.3