priqueue.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:5k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
  2. /*
  3.  * Copyright (c) 1997 Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  * 3. All advertising materials mentioning features or use of this software
  15.  *    must display the following acknowledgement:
  16.  * This product includes software developed by the Computer Systems
  17.  * Engineering Group at Lawrence Berkeley Laboratory.
  18.  * 4. Neither the name of the University nor of the Laboratory may be used
  19.  *    to endorse or promote products derived from this software without
  20.  *    specific prior written permission.
  21.  *
  22.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  23.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  26.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  27.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  28.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  29.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  31.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  32.  * SUCH DAMAGE.
  33.  */
  34. /* Ported from CMU/Monarch's code, nov'98 -Padma.*/
  35. /* -*- c++ -*-
  36.    priqueue.cc
  37.    
  38.    A simple priority queue with a remove packet function
  39.    $Id: priqueue.cc,v 1.7 2004/10/07 17:56:03 haldar Exp $
  40.    */
  41. #include <object.h>
  42. #include <queue.h>
  43. #include <drop-tail.h>
  44. #include <packet.h>
  45. #include <cmu-trace.h>
  46. #include "priqueue.h"
  47. typedef int (*PacketFilter)(Packet *, void *);
  48. PriQueue_List PriQueue::prhead = { 0 };
  49. static class PriQueueClass : public TclClass {
  50. public:
  51.   PriQueueClass() : TclClass("Queue/DropTail/PriQueue") {}
  52.   TclObject* create(int, const char*const*) {
  53.     return (new PriQueue);
  54.   }
  55. } class_PriQueue;
  56. PriQueue::PriQueue() : DropTail()
  57. {
  58.         bind("Prefer_Routing_Protocols", &Prefer_Routing_Protocols);
  59. LIST_INSERT_HEAD(&prhead, this, link);
  60. }
  61. int
  62. PriQueue::command(int argc, const char*const* argv)
  63. {
  64.   if (argc == 2 && strcasecmp(argv[1], "reset") == 0)
  65.     {
  66.       Terminate();
  67.       //FALL-THROUGH to give parents a chance to reset
  68.     }
  69.   return DropTail::command(argc, argv);
  70. }
  71. void
  72. PriQueue::recv(Packet *p, Handler *h)
  73. {
  74.         struct hdr_cmn *ch = HDR_CMN(p);
  75.         if(Prefer_Routing_Protocols) {
  76.                 switch(ch->ptype()) {
  77. case PT_DSR:
  78. case PT_MESSAGE:
  79.                 case PT_TORA:
  80.                 case PT_AODV:
  81.                         recvHighPriority(p, h);
  82.                         break;
  83.                 default:
  84.                         Queue::recv(p, h);
  85.                 }
  86.         }
  87.         else {
  88.                 Queue::recv(p, h);
  89.         }
  90. }
  91. void 
  92. PriQueue::recvHighPriority(Packet *p, Handler *)
  93.   // insert packet at front of queue
  94. {
  95. q_->enqueHead(p);
  96. if (q_->length() >= qlim_)
  97.     {
  98.       Packet *to_drop = q_->lookup(q_->length()-1);
  99.       q_->remove(to_drop);
  100.       drop(to_drop);
  101.     }
  102.   
  103.   if (!blocked_) {
  104.     /*
  105.      * We're not blocked.  Get a packet and send it on.
  106.      * We perform an extra check because the queue
  107.      * might drop the packet even if it was
  108.      * previously empty!  (e.g., RED can do this.)
  109.      */
  110.     p = deque();
  111.     if (p != 0) {
  112.       blocked_ = 1;
  113.       target_->recv(p, &qh_);
  114.     }
  115.   } 
  116. }
  117.  
  118. void 
  119. PriQueue::filter(PacketFilter filter, void * data)
  120.   // apply filter to each packet in queue, 
  121.   // - if filter returns 0 leave packet in queue
  122.   // - if filter returns 1 remove packet from queue
  123. {
  124.   int i = 0;
  125.   while (i < q_->length())
  126.     {
  127.       Packet *p = q_->lookup(i);
  128.       if (filter(p,data))
  129. {
  130.   q_->remove(p); // decrements q len
  131. }
  132.       else i++;
  133.     }
  134. }
  135. Packet*
  136. PriQueue::filter(nsaddr_t id)
  137. {
  138. Packet *p = 0;
  139. Packet *pp = 0;
  140. struct hdr_cmn *ch;
  141. for(p = q_->head(); p; p = p->next_) {
  142. ch = HDR_CMN(p);
  143. if(ch->next_hop() == id)
  144. break;
  145. pp = p;
  146. }
  147. /*
  148.  * Deque Packet
  149.  */
  150. if(p) {
  151. if(pp == 0)
  152. q_->remove(p);
  153. else
  154. q_->remove(p, pp);
  155. }
  156. return p;
  157. }
  158. /*
  159.  * Called at the end of the simulation to purge the IFQ.
  160.  */
  161. void
  162. PriQueue::Terminate()
  163. {
  164. Packet *p;
  165. while((p = deque())) {
  166. drop(p, DROP_END_OF_SIMULATION);
  167. //drop(p);
  168. }
  169. }