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

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
  2. /*
  3.  * Copyright (c) 1990-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.  *
  35.  * Here is one set of parameters from one of Sally's simulations
  36.  * (this is from tcpsim, the older simulator):
  37.  * 
  38.  * ed [ q_weight=0.002 thresh=5 linterm=30 maxthresh=15
  39.  *         mean_pktsize=500 dropmech=random-drop queue-size=60
  40.  *         plot-file=none bytes=false doubleq=false dqthresh=50 
  41.  *    wait=true ]
  42.  * 
  43.  * 1/"linterm" is the max probability of dropping a packet. 
  44.  * There are different options that make the code
  45.  * more messy that it would otherwise be.  For example,
  46.  * "doubleq" and "dqthresh" are for a queue that gives priority to
  47.  *   small (control) packets, 
  48.  * "bytes" indicates whether the queue should be measured in bytes 
  49.  *   or in packets, 
  50.  * "dropmech" indicates whether the drop function should be random-drop 
  51.  *   or drop-tail when/if the queue overflows, and 
  52.  *   the commented-out Holt-Winters method for computing the average queue 
  53.  *   size can be ignored.
  54.  * "wait" indicates whether the gateway should wait between dropping
  55.  *   packets.
  56.  */
  57. /* Bugreport about rio.cc:
  58.  *
  59.  * David Ros and LuiWei have both reported, in June 2002 and in May 2001,
  60.  * that rio.cc has a bug in that RIO does not calculate a new average
  61.  * queue length when an OUT packet arrives.
  62.  * 
  63.  * This bug has not been checked or repaired.
  64.  */
  65. #ifndef lint
  66. static const char rcsid[] =
  67.     "@(#) $Header: /cvsroot/nsnam/ns-2/queue/rio.cc,v 1.13 2006/12/17 15:21:59 mweigle Exp $ (LBL)";
  68. #endif
  69. #include "rio.h"
  70. #include "tclcl.h"
  71. #include "packet.h"
  72. #include "random.h"
  73. #include "flags.h"
  74. #include "delay.h"
  75. #include "template.h"
  76. #include "red.h"
  77. static class RIOClass : public TclClass {
  78. public:
  79. RIOClass() : TclClass("Queue/RED/RIO") {}
  80. TclObject* create(int, const char*const*) {
  81. return (new RIOQueue);
  82. }
  83. } class_rio;
  84. RIOQueue::RIOQueue() : in_len_(0), in_bcount_(0), in_idle_(1)
  85. {
  86. bind("in_thresh_", &edp_in_.th_min);     // In_minthresh
  87. bind("in_maxthresh_", &edp_in_.th_max);     // In_maxthresh
  88. bind("out_thresh_", &edp_out_.th_min);     // Out_minthresh
  89. bind("out_maxthresh_", &edp_out_.th_max);   // Out_maxthresh
  90. bind("in_linterm_", &edp_in_.max_p_inv);
  91. /* added by ratul- allows a finer control over the policy.
  92.    gentle automatically means both the below are gentle */
  93. bind_bool("in_gentle_",&edp_in_.gentle);    // drop prob. slowly
  94. bind_bool("out_gentle_",&edp_out_.gentle);  // when ave queue
  95.     // exceeds maxthresh
  96. bind("in_ave_", &edv_in_.v_ave);     // In average queue sie
  97. bind("out_ave_", &edv_out_.v_ave);     // Out average queue sie
  98. bind("in_prob1_", &edv_in_.v_prob1);     // In dropping probability
  99. bind("out_prob1_", &edv_out_.v_prob1);     // Out dropping probability
  100. bind("priority_method_", &priority_method_); // method for setting
  101.     // priority
  102. // q_ = new PacketQueue();     // underlying queue
  103. // pq_ = q_;
  104. // reset();
  105. }
  106. void RIOQueue::reset()
  107. {
  108. /*
  109.  * If queue is measured in bytes, scale min/max thresh
  110.  * by the size of an average packet (which is specified by user).
  111.  */
  112. if (qib_) {
  113. edp_in_.th_min *= edp_.mean_pktsize;
  114. edp_in_.th_max *= edp_.mean_pktsize;
  115. edp_out_.th_min *= edp_.mean_pktsize;
  116. edp_out_.th_max *= edp_.mean_pktsize;
  117. }
  118. //modified - ratul
  119. if (edp_.gentle) {
  120. edp_in_.gentle = true;
  121. edp_out_.gentle = true;
  122. }
  123. if (edp_in_.gentle) {
  124. edv_in_.v_c = ( 1.0 - 1 / edp_in_.max_p_inv ) / edp_in_.th_max;
  125. edv_in_.v_d = 2 / edp_in_.max_p_inv - 1.0;
  126. }
  127. if (edp_out_.gentle) {
  128. edv_out_.v_c = ( 1.0 - 1 / edp_.max_p_inv ) / edp_out_.th_max;
  129. edv_out_.v_d = 2 / edp_.max_p_inv - 1.0;
  130. }
  131.         /* Added by Wenjia */
  132.         edv_in_.v_ave = 0.0;
  133.         edv_in_.v_slope = 0.0;
  134.         edv_in_.drops = 0;
  135.         edv_in_.count = 0;
  136.         edv_in_.count_bytes = 0;
  137.         edv_in_.old = 0;
  138.         edv_in_.v_a = 1 / (edp_in_.th_max - edp_in_.th_min);
  139.         edv_in_.v_b = - edp_in_.th_min / (edp_in_.th_max - edp_in_.th_min);
  140.         /* Added by Wenjia */
  141.         edv_out_.v_ave = 0.0;
  142.         edv_out_.v_slope = 0.0;
  143.         edv_out_.drops = 0;
  144.         edv_out_.count = 0;
  145.         edv_out_.count_bytes = 0;
  146.         edv_out_.old = 0;
  147.         edv_out_.v_a = 1 / (edp_out_.th_max - edp_out_.th_min);
  148.         edv_out_.v_b = - edp_out_.th_min / (edp_out_.th_max - edp_out_.th_min);
  149. in_idle_ = 1;
  150. if (&Scheduler::instance() == NULL) {
  151. in_idletime_ = 0.0; /* sched not instantiated yet */
  152.         }     
  153. REDQueue::reset();
  154. }
  155. /*
  156.  * Return the next packet in the queue for transmission.
  157.  */
  158. Packet* RIOQueue::deque()
  159. {
  160. Packet *p;
  161. p = REDQueue::deque();
  162.         // printf( "qlen %d %dn", q_->length(), length());
  163. if (p != 0) {
  164. hdr_flags* hf = hdr_flags::access(p);
  165.                 if (hf->pri_) {   
  166.   /* Regular In packets */
  167.                   in_idle_ = 0;
  168.   in_bcount_ -= hdr_cmn::access(p)->size();
  169.   --in_len_;
  170. }
  171. } else {
  172.                 in_idle_ = 1;
  173. }
  174. return (p);
  175. }
  176. /*
  177.  * should the packet be dropped/marked due to a probabilistic drop?
  178.  */
  179. int
  180. RIOQueue::drop_in_early(Packet* pkt)
  181. {
  182. hdr_cmn* ch = hdr_cmn::access(pkt);
  183.         edv_in_.v_prob1 = REDQueue::calculate_p(edv_in_.v_ave, edp_in_.th_max, 
  184.   edp_in_.gentle, edv_in_.v_a, edv_in_.v_b, edv_in_.v_c, 
  185.   edv_in_.v_d, edp_in_.max_p_inv);
  186.         edv_in_.v_prob = REDQueue::modify_p(edv_in_.v_prob1, edv_in_.count, 
  187.   edv_in_.count_bytes, edp_.bytes, edp_.mean_pktsize, edp_.wait, 
  188.   ch->size());
  189. // drop probability is computed, pick random number and act
  190. double u = Random::uniform();
  191. if (u <= edv_in_.v_prob) {
  192. // DROP or MARK
  193. edv_in_.count = 0;
  194. edv_in_.count_bytes = 0;
  195. hdr_flags* hf = hdr_flags::access(pickPacketForECN(pkt));
  196. if (edp_.setbit && hf->ect() && 
  197. edv_in_.v_ave < edp_in_.th_max) {
  198. hf->ce() = 1;  // mark Congestion Experienced bit
  199. return (0); // no drop
  200. } else {
  201. return (1); // drop
  202. }
  203. }
  204. return (0); // no DROP/mark
  205. }
  206. /*
  207.  * Obsolete note from original version of code:
  208.  * The rationale here is that if the edv_in_.v_ave is close
  209.  * to the edp_in_.th_max, (we are about to turn over to the
  210.  * congestion control phase, presumably because of Out packets),
  211.  * then we should drop Out packets more severely.
  212.  */
  213. int RIOQueue::drop_out_early(Packet* pkt)
  214. {
  215.         hdr_cmn* ch = hdr_cmn::access(pkt);
  216.         edv_out_.v_prob1 = REDQueue::calculate_p(edv_.v_ave, edp_out_.th_max, 
  217.   edp_out_.gentle, edv_out_.v_a, edv_out_.v_b, edv_out_.v_c, 
  218.   edv_out_.v_d, edp_.max_p_inv);
  219.         edv_out_.v_prob = REDQueue::modify_p(edv_out_.v_prob1, edv_out_.count, 
  220.   edv_out_.count_bytes, edp_.bytes, edp_.mean_pktsize, edp_.wait, 
  221.   ch->size());
  222.         // drop probability is computed, pick random number and act
  223.         double u = Random::uniform();
  224.         if (u <= edv_out_.v_prob) {
  225.             // DROP or MARK
  226.             edv_out_.count = 0;
  227.             edv_out_.count_bytes = 0;
  228.             hdr_flags* hf = hdr_flags::access(pickPacketForECN(pkt));
  229.             if (edp_.setbit && hf->ecn_capable_ &&
  230. edv_.v_ave < edp_out_.th_max) {
  231. hf->ce() = 1;  // mark Congestion Experienced bit
  232. return (0); // no drop
  233.               } else {
  234.               return (1);
  235.               }
  236.         }
  237.         return (0);  // no DROP/mark
  238. }
  239. /*
  240.  * Receive a new packet arriving at the queue.
  241.  * The average queue size is computed.  If the average size
  242.  * exceeds the threshold, then the dropping probability is computed,
  243.  * and the newly-arriving packet is dropped with that probability.
  244.  * The packet is also dropped if the maximum queue size is exceeded.
  245.  *
  246.  * "Forced" drops mean a packet arrived when the underlying queue was
  247.  * full or when the average q size exceeded maxthresh.
  248.  * "Unforced" means a RED random drop.
  249.  *
  250.  * For forced drops, either the arriving packet is dropped or one in the
  251.  * queue is dropped, depending on the setting of drop_tail_.
  252.  * For unforced drops, the arriving packet is always the victim.
  253.  */
  254. #define DTYPE_NONE 0 /* ok, no drop */
  255. #define DTYPE_FORCED 1 /* a "forced" drop */
  256. #define DTYPE_UNFORCED 2 /* an "unforced" (random) drop */
  257. void RIOQueue::enque(Packet* pkt)
  258. {
  259.         /* Duplicate the RED algorithm to carry out a separate
  260.          * calculation for Out packets -- Wenjia */
  261. hdr_flags* hf = hdr_flags::access(pkt);
  262. hdr_ip* iph = hdr_ip::access(pkt);
  263. if (priority_method_ == 1) {
  264. hf->pri_ = iph->flowid();
  265. }
  266. //printf("RIOQueue::enque queue %d queue-length %d priority %dn", 
  267. //      q_, q_->length(), hf->pri_);
  268.         if (hf->pri_) {  /* Regular In packets */
  269. /*
  270.  * if we were idle, we pretend that m packets arrived during
  271.  * the idle period.  m is set to be the ptc times the amount
  272.  * of time we've been idle for
  273.  */
  274. int m = 0;
  275. int m_in = 0;
  276. double now = Scheduler::instance().clock();
  277.         /* To account for the period when the queue was empty.  */
  278. if (in_idle_) {
  279. in_idle_ = 0;
  280. m_in = int(edp_.ptc * (now - idletime_));
  281. if (idle_) {
  282.                 idle_ = 0;
  283.                 m = int(edp_.ptc * (now - idletime_));
  284.         }
  285. /*
  286.  * Run the estimator with either 1 new packet arrival, or with
  287.  * the scaled version above [scaled by m due to idle time]
  288.  */
  289.         // printf( "qlen %dn", q_->length());
  290. edv_.v_ave = REDQueue::estimator(qib_ ? q_->byteLength() : q_->length(), m + 1,
  291. edv_.v_ave, edp_.q_w);
  292. edv_in_.v_ave = REDQueue::estimator(qib_ ? in_bcount_ : in_len_,
  293. m_in + 1, edv_in_.v_ave, edp_.q_w);
  294. /*
  295.  * count and count_bytes keeps a tally of arriving traffic
  296.  * that has not been dropped (i.e. how long, in terms of traffic,
  297.  * it has been since the last early drop)
  298.  */
  299. hdr_cmn* ch = hdr_cmn::access(pkt);
  300. ++edv_.count;
  301. edv_.count_bytes += ch->size();
  302.         /* added by Yun */
  303.         ++edv_in_.count;
  304.         edv_in_.count_bytes += ch->size();
  305. /*
  306.  * DROP LOGIC:
  307.  * q = current q size, ~q = averaged q size
  308.  * 1> if ~q > maxthresh, this is a FORCED drop
  309.  * 2> if minthresh < ~q < maxthresh, this may be an UNFORCED drop
  310.  * 3> if (q+1) > hard q limit, this is a FORCED drop
  311.  */
  312. // register double qavg = edv_.v_ave;
  313. register double in_qavg = edv_in_.v_ave;
  314. int droptype = DTYPE_NONE;
  315. int qlen = qib_ ? q_->byteLength() : q_->length();
  316. int in_qlen = qib_ ? in_bcount_ : in_len_;
  317. int qlim = qib_ ? (qlim_ * edp_.mean_pktsize) : qlim_;
  318. curq_ = qlen; // helps to trace queue during arrival, if enabled
  319. if (in_qavg >= edp_in_.th_min && in_qlen > 1) {
  320. if ((!edp_in_.gentle && in_qavg >= edp_in_.th_max) ||
  321. (edp_in_.gentle && in_qavg >= 2 * edp_in_.th_max)) {
  322. droptype = DTYPE_FORCED;
  323. } else if (edv_in_.old == 0) {
  324. /* 
  325.  * The average queue size has just crossed the
  326.  * threshold from below to above "minthresh", or
  327.  * from above "minthresh" with an empty queue to
  328.  * above "minthresh" with a nonempty queue.
  329.  */
  330. edv_in_.count = 1;
  331. edv_in_.count_bytes = ch->size();
  332. edv_in_.old = 1;
  333. } else if (drop_in_early(pkt)) {
  334. droptype = DTYPE_UNFORCED;
  335. }
  336. } else {
  337. /* No packets are being dropped.  */
  338. edv_in_.v_prob = 0.0;
  339. edv_in_.old = 0;
  340. }
  341. if (qlen >= qlim) {
  342. // see if we've exceeded the queue size
  343. droptype = DTYPE_FORCED;
  344. }
  345. if (droptype == DTYPE_UNFORCED) {
  346. /* pick packet for ECN, which is dropping in this case */
  347. Packet *pkt_to_drop = pickPacketForECN(pkt);
  348. /* 
  349.  * If the packet picked is different that the one that just
  350.  * arrived, add it to the queue and remove the chosen packet.
  351.  */
  352. if (pkt_to_drop != pkt) {
  353. q_->enque(pkt);
  354.                         // printf( "in: qlen %d %dn", q_->length(), length());
  355.                         ++in_len_;
  356. in_bcount_ += ch->size();
  357. q_->remove(pkt_to_drop);
  358.                         // printf("remove qlen %d %dn",q_->length(),length());
  359.                         if (hdr_flags::access(pkt_to_drop)->pri_)
  360.                            {
  361.                              in_bcount_ -= 
  362.      hdr_cmn::access(pkt_to_drop)->size();
  363.                              --in_len_;
  364.                            }
  365. pkt = pkt_to_drop; /* ok 'cause pkt not needed anymore */
  366. }
  367. // deliver to special "edrop" target, if defined
  368. if (de_drop_ != NULL)
  369. de_drop_->recv(pkt);
  370. else
  371. drop(pkt);
  372. } else {
  373. /* forced drop, or not a drop: first enqueue pkt */
  374. q_->enque(pkt);
  375.                 // printf( "in: qlen %d %dn", q_->length(), length());
  376.                 ++in_len_;
  377. in_bcount_ += ch->size();
  378. /* drop a packet if we were told to */
  379. if (droptype == DTYPE_FORCED) {
  380. /* drop random victim or last one */
  381. pkt = pickPacketToDrop();
  382. q_->remove(pkt);
  383.                         // printf("remove qlen %d %dn",q_->length(),length());
  384.                         if (hdr_flags::access(pkt)->pri_) {
  385.                           in_bcount_ -= hdr_cmn::access(pkt)->size(); 
  386.                           --in_len_;
  387.                           }
  388. drop(pkt);
  389. if (!ns1_compat_) {
  390. // bug-fix from Philip Liu, <phill@ece.ubc.ca>
  391. edv_.count = 0;
  392. edv_.count_bytes = 0;
  393. edv_in_.count = 0;
  394. edv_in_.count_bytes = 0;
  395. }
  396. }
  397.             }
  398.         }
  399. else {     /* Out packets and default regular packets */
  400.           /*
  401.            * count and count_bytes keeps a tally of arriving traffic
  402.            * that has not been dropped (i.e. how long, in terms of traffic,
  403.            * it has been since the last early drop)
  404.            */
  405.           hdr_cmn* ch = hdr_cmn::access(pkt);
  406.           ++edv_.count;
  407.           edv_.count_bytes += ch->size();
  408.           /* added by Yun */
  409.           ++edv_out_.count;
  410.           edv_out_.count_bytes += ch->size();
  411.           /*
  412.            * DROP LOGIC:
  413.            *    q = current q size, ~q = averaged q size
  414.            *    1> if ~q > maxthresh, this is a FORCED drop
  415.            *    2> if minthresh < ~q < maxthresh, this may be an UNFORCED drop
  416.            *    3> if (q+1) > hard q limit, this is a FORCED drop
  417.            */
  418.                 /* if the average queue is below the out_th_min
  419.                  * then we have no need to worry.
  420.                  */
  421.           register double qavg = edv_.v_ave;
  422.           // register double in_qavg = edv_in_.v_ave;
  423.           int droptype = DTYPE_NONE;
  424.           int qlen = qib_ ? q_->byteLength() : q_->length();
  425.           /* added by Yun, seems not useful */
  426.           // int out_qlen = qib_ ? out_bcount_ : q_->out_length();
  427.           int qlim = qib_ ?  (qlim_ * edp_.mean_pktsize) : qlim_;
  428.           curq_ = qlen; // helps to trace queue during arrival, if enabled
  429.           if (qavg >= edp_out_.th_min && qlen > 1) {
  430.                   if (!edp_out_.gentle && qavg >= edp_out_.th_max ||
  431.       (edp_out_.gentle && qavg >= 2 * edp_out_.th_max)) {
  432.                         droptype = DTYPE_FORCED;  // ? not sure, Yun
  433.                   } else if (edv_out_.old == 0) {
  434. /* 
  435.  * The average queue size has just crossed the
  436.  * threshold from below to above "minthresh", or
  437.  * from above "minthresh" with an empty queue to
  438.  * above "minthresh" with a nonempty queue.
  439.  */
  440.                         edv_out_.count = 1;
  441.                         edv_out_.count_bytes = ch->size();
  442.                         edv_out_.old = 1;
  443.                   } else if (drop_out_early(pkt)) {
  444.                         droptype = DTYPE_UNFORCED; // ? not sure, Yun
  445.                   }
  446.           } else {
  447.                   edv_out_.v_prob = 0.0;
  448.                   edv_out_.old = 0;              // explain
  449.           }
  450.           if (qlen >= qlim) {
  451.                   // see if we've exceeded the queue size
  452.                   droptype = DTYPE_FORCED;   //need more consideration, Yun
  453.           }
  454.           if (droptype == DTYPE_UNFORCED) {
  455.                   /* pick packet for ECN, which is dropping in this case */
  456.                   Packet *pkt_to_drop = pickPacketForECN(pkt);
  457.                   /*
  458.                    * If the packet picked is different that the one that just
  459.                    * arrived, add it to the queue and remove the chosen packet.
  460.                    */
  461.                   if (pkt_to_drop != pkt) {
  462.                           q_->enque(pkt);
  463.   //printf("out: qlen %d %dn", q_->length(), length());
  464.                           q_->remove(pkt_to_drop);
  465.   //printf("remove qlen %d %dn",q_->length(),length());
  466.                           if (hdr_flags::access(pkt_to_drop)->pri_)
  467.   {
  468.                              in_bcount_ -=hdr_cmn::access(pkt_to_drop)->size();
  469.      --in_len_;
  470.   }
  471.                           pkt = pkt_to_drop;/* ok cause pkt not needed anymore */
  472.                   }
  473.                   // deliver to special "edrop" target, if defined
  474.                   if (de_drop_ != NULL)
  475.                           de_drop_->recv(pkt);
  476.                   else
  477.                           drop(pkt);
  478.           } else {
  479.                   /* forced drop, or not a drop: first enqueue pkt */
  480.                   q_->enque(pkt);
  481.   //printf("out: qlen %d %dn", q_->length(), length());
  482.                   /* drop a packet if we were told to */
  483.                   if (droptype == DTYPE_FORCED) {
  484.                           /* drop random victim or last one */
  485.                           pkt = pickPacketToDrop();
  486.                           q_->remove(pkt);
  487.   //printf("remove qlen %d %dn",q_->length(),length());
  488.                           if (hdr_flags::access(pkt)->pri_)
  489.   {
  490.                             in_bcount_ -= hdr_cmn::access(pkt)->size();
  491.     --in_len_;
  492.   }
  493.                           drop(pkt);
  494.                   }
  495.           }
  496. }
  497. return;
  498. }
  499. /*
  500.  * Routine called by TracedVar facility when variables change values.
  501.  * Currently used to trace values of avg queue size, drop probability,
  502.  * and the instantaneous queue size seen by arriving packets.
  503.  * Note that the tracing of each var must be enabled in tcl to work.
  504.  */
  505. void
  506. RIOQueue::trace(TracedVar* v)
  507. {
  508. char wrk[500];
  509. const char *p;
  510. if (((p = strstr(v->name(), "ave")) == NULL) &&
  511.     ((p = strstr(v->name(), "in_ave")) == NULL) &&
  512.     ((p = strstr(v->name(), "out_ave")) == NULL) &&
  513.     ((p = strstr(v->name(), "prob")) == NULL) &&
  514.     ((p = strstr(v->name(), "in_prob")) == NULL) &&
  515.     ((p = strstr(v->name(), "out_prob")) == NULL) &&
  516.     ((p = strstr(v->name(), "curq")) == NULL)) {
  517. fprintf(stderr, "RIO:unknown trace var %sn",
  518. v->name());
  519. return;
  520. }
  521. if (tchan_) {
  522. int n;
  523. double t = Scheduler::instance().clock();
  524. // XXX: be compatible with nsv1 RED trace entries
  525. if (*p == 'c') {
  526. sprintf(wrk, "Q %g %d", t, int(*((TracedInt*) v)));
  527. } else {
  528. sprintf(wrk, "%c %g %g", *p, t,
  529. double(*((TracedDouble*) v)));
  530. }
  531. n = strlen(wrk);
  532. wrk[n] = 'n'; 
  533. wrk[n+1] = 0;
  534. (void)Tcl_Write(tchan_, wrk, n+1);
  535. }
  536. return; 
  537. }
  538. /* for debugging help */
  539. void RIOQueue::print_edp()
  540. {
  541. REDQueue::print_edp();
  542. printf("in_minth: %f, in_maxth: %fn", edp_in_.th_min, edp_in_.th_max);
  543. printf("out_minth: %f, out_maxth: %fn", 
  544.                 edp_out_.th_min, edp_out_.th_max);
  545. printf("qlim: %d, in_idletime: %fn", qlim_, in_idletime_);
  546. printf("=========n");
  547. }
  548. void RIOQueue::print_edv()
  549. {
  550. REDQueue::print_edv();
  551. printf("in_v_a: %f, in_v_b: %fn", edv_in_.v_a, edv_in_.v_b);
  552. printf("out_v_a: %f, out_v_b: %fn", edv_out_.v_a, edv_out_.v_b);
  553. }