delayer.cc

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2003  International Computer Science Institute
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. All advertising materials mentioning features or use of this software
00014  *    must display the following acknowledgement:
00015  *      This product includes software developed by ICIR, the ICSI
00016  *      Center for Internet Research (ICSI: the International Computer
00017  *      Science Institute).
00018  * 4. Neither the name of ICIR nor of ICSI 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 ICSI 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 ICSI 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  */
00035 
00036 #include "delayer.h"
00037 
00038 Delayer::Delayer() : Connector(), last_sent(-100000), alloc_int(NULL), 
00039 alloc_len(NULL),  alloc_free(1), at_(*this), 
00040 spike_int(NULL), spike_len(NULL), spike_free(1),
00041 st_(*this), target_free(1), th_ (*this), prev_h_(NULL), pkt_(NULL) {
00042 }
00043  
00044 void Delayer::recv(Packet* p, Handler* h) {
00045     double now = Scheduler::instance().clock();         
00046 
00047     if (pkt_ != NULL) {
00048         printf("delayer not empty!\n");
00049         exit(1);
00050     }
00051 
00052     prev_h_ = h;
00053     pkt_ = p;
00054 
00055         // if queue has been empty then trigger channel allocation delay
00056         if (alloc_len && now - last_sent > alloc_int->value()) {        
00057                         alloc_free = 0;
00058                         at_.resched(alloc_len->value());
00059                         return;
00060         }
00061     try_send();
00062 }
00063 
00064 void Delayer::try_send() {
00065     double now = Scheduler::instance().clock();         
00066     
00067     if (debug_)
00068             printf("now %f last_sent %f alloc_free %d target_free %d, spike_free %d\n", 
00069             now, last_sent, alloc_free, target_free, spike_free);
00070 
00071     if (!target_free || !alloc_free || !spike_free)
00072         return;
00073 
00074     if (pkt_ && target_) {
00075                 target_->recv(pkt_, &th_);
00076         last_sent = Scheduler::instance().clock();      
00077         target_free = 0;
00078         pkt_ = NULL;
00079     }
00080     if (prev_h_)
00081         prev_h_->handle(&e);
00082 }
00083 
00084 int Delayer::command(int argc, const char*const* argv) {
00085         // explicitly block the queue to model a delay spike
00086         if (argc == 2 && !strcmp(argv[1],"block") 
00087     && !spike_len 
00088     ) {
00089             spike_free = 0;
00090             return (TCL_OK);
00091         }
00092         if (argc == 2 && !strcmp(argv[1],"unblock") 
00093     //  && !spike_len
00094     ) {
00095                 spike_free = 1;
00096                 try_send();
00097                 return (TCL_OK);
00098         }
00099         // set distributions for channel allocation delay
00100         if (argc == 4 && !strcmp(argv[1],"alloc")) {
00101                 alloc_int = (RandomVariable *)TclObject::lookup(argv[2]);
00102                 alloc_len = (RandomVariable *)TclObject::lookup(argv[3]);
00103                 return (TCL_OK);
00104         }
00105         // set distributions for delay spikes
00106         if (argc == 4 && !strcmp(argv[1],"spike")) {
00107                 spike_int = (RandomVariable *)TclObject::lookup(argv[2]);
00108                 spike_len = (RandomVariable *)TclObject::lookup(argv[3]);
00109         st_.sched(getNextSpikeInt());
00110                 return (TCL_OK);
00111         }
00112         return Connector::command(argc, argv);
00113 }
00114 
00115 void SpikeTimer::expire(Event*) {
00116 //  printf("SpikeHandler, spike_free %d\n", delayer_.getSpike());
00117     if (delayer_.getSpike()) {
00118             delayer_.takeSpike();
00119                 resched(delayer_.getNextSpikeLen());
00120                 return;
00121     }
00122     delayer_.freeSpike();
00123     resched(delayer_.getNextSpikeInt());
00124     delayer_.try_send();
00125 }
00126 
00127 void AllocTimer::expire(Event*) {
00128     delayer_.freeAlloc(); 
00129     delayer_.try_send();
00130 //  printf("AllocHandler\n");
00131 }
00132 
00133 void TargetHandler::handle(Event*) {
00134     delayer_.freeTarget(); 
00135     delayer_.try_send();
00136 //  printf("TargetHandler\n");
00137 }
00138 

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