mac-timers.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  * Contributions by:
00036  *   - Mike Holland
00037  */
00038 
00039 #include <delay.h>
00040 #include <connector.h>
00041 #include <packet.h>
00042 #include <random.h>
00043  
00044 // #define DEBUG
00045 //#include <debug.h>
00046 #include <arp.h>
00047 #include <ll.h>
00048 #include <mac.h>
00049 #include <mac-timers.h>
00050 #include <mac-802_11.h> 
00051 
00052 /*
00053  * Force timers to expire on slottime boundries.
00054  */
00055 // #define USE_SLOT_TIME
00056 
00057 // change wrt Mike's code
00058 
00059  #ifdef USE_SLOT_TIME
00060  #error "Incorrect slot time implementation - don't use USE_SLOT_TIME..."
00061  #endif
00062 
00063 #define ROUND_TIME()    \
00064     {                               \
00065         assert(slottime);                   \
00066         double rmd = remainder(s.clock() + rtime, slottime);    \
00067         if(rmd > 0.0)                       \
00068             rtime += (slottime - rmd);          \
00069         else                            \
00070             rtime += (-rmd);                \
00071     }
00072 
00073 
00074 /* ======================================================================
00075    Timers
00076    ====================================================================== */
00077 
00078 void
00079 MacTimer::start(double time)
00080 {
00081     Scheduler &s = Scheduler::instance();
00082     assert(busy_ == 0);
00083 
00084     busy_ = 1;
00085     paused_ = 0;
00086     stime = s.clock();
00087     rtime = time;
00088     assert(rtime >= 0.0);
00089 
00090 
00091     s.schedule(this, &intr, rtime);
00092 }
00093 
00094 void
00095 MacTimer::stop(void)
00096 {
00097     Scheduler &s = Scheduler::instance();
00098 
00099     assert(busy_);
00100 
00101     if(paused_ == 0)
00102         s.cancel(&intr);
00103 
00104     busy_ = 0;
00105     paused_ = 0;
00106     stime = 0.0;
00107     rtime = 0.0;
00108 }
00109 
00110 /* ======================================================================
00111    Defer Timer
00112    ====================================================================== */
00113 void
00114 DeferTimer::start(double time)
00115 {
00116     Scheduler &s = Scheduler::instance();
00117 
00118     assert(busy_ == 0);
00119 
00120     busy_ = 1;
00121     paused_ = 0;
00122     stime = s.clock();
00123     rtime = time;
00124 #ifdef USE_SLOT_TIME
00125     ROUND_TIME();
00126 #endif
00127     assert(rtime >= 0.0);
00128 
00129     s.schedule(this, &intr, rtime);
00130 }
00131 
00132 
00133 void    
00134 DeferTimer::handle(Event *)
00135 {       
00136     busy_ = 0;
00137     paused_ = 0;
00138     stime = 0.0;
00139     rtime = 0.0;
00140 
00141 
00142 
00143     mac->deferHandler();
00144 }
00145 
00146 
00147 /* ======================================================================
00148    NAV Timer
00149    ====================================================================== */
00150 void    
00151 NavTimer::handle(Event *)
00152 {       
00153     busy_ = 0;
00154     paused_ = 0;
00155     stime = 0.0;
00156     rtime = 0.0;
00157 
00158     mac->navHandler();
00159 }
00160 
00161 
00162 /* ======================================================================
00163    Receive Timer
00164    ====================================================================== */
00165 void    
00166 RxTimer::handle(Event *)
00167 {       
00168     busy_ = 0;
00169     paused_ = 0;
00170     stime = 0.0;
00171     rtime = 0.0;
00172 
00173     mac->recvHandler();
00174 }
00175 
00176 
00177 /* ======================================================================
00178    Send Timer
00179    ====================================================================== */
00180 void    
00181 TxTimer::handle(Event *)
00182 {       
00183     busy_ = 0;
00184     paused_ = 0;
00185     stime = 0.0;
00186     rtime = 0.0;
00187 
00188 
00189 
00190     mac->sendHandler();
00191 }
00192 
00193 
00194 /* ======================================================================
00195    Interface Timer
00196    ====================================================================== */
00197 void
00198 IFTimer::handle(Event *)
00199 {
00200     busy_ = 0;
00201     paused_ = 0;
00202     stime = 0.0;
00203     rtime = 0.0;
00204 
00205     mac->txHandler();
00206 }
00207 
00208 
00209 /* ======================================================================
00210    Backoff Timer
00211    ====================================================================== */
00212 void
00213 BackoffTimer::handle(Event *)
00214 {
00215     busy_ = 0;
00216     paused_ = 0;
00217     stime = 0.0;
00218     rtime = 0.0;
00219     difs_wait = 0.0;
00220 
00221     mac->backoffHandler();
00222 }
00223 
00224 void
00225 BackoffTimer::start(int cw, int idle)
00226 {
00227     Scheduler &s = Scheduler::instance();
00228 
00229     assert(busy_ == 0);
00230 
00231     busy_ = 1;
00232     paused_ = 0;
00233     stime = s.clock();
00234     
00235     rtime = (Random::random() % cw) * mac->phymib_.getSlotTime();
00236 
00237 
00238 
00239 #ifdef USE_SLOT_TIME
00240     ROUND_TIME();
00241 #endif
00242     difs_wait = 0.0;
00243 
00244     if(idle == 0)
00245         paused_ = 1;
00246     else {
00247         assert(rtime >= 0.0);
00248         s.schedule(this, &intr, rtime);
00249     }
00250 }
00251 
00252 
00253 void
00254 BackoffTimer::pause()
00255 {
00256     Scheduler &s = Scheduler::instance();
00257 
00258     //the caculation below make validation pass for linux though it
00259     // looks dummy
00260 
00261     double st = s.clock();
00262     double rt = stime + difs_wait;
00263     double sr = st - rt;
00264     double mst = (mac->phymib_.getSlotTime());
00265 
00266 
00267 
00268         int slots = int (sr/mst);
00269 
00270     if(slots < 0)
00271         slots = 0;
00272     assert(busy_ && ! paused_);
00273 
00274     paused_ = 1;
00275     rtime -= (slots * mac->phymib_.getSlotTime());
00276 
00277 
00278     assert(rtime >= 0.0);
00279 
00280     difs_wait = 0.0;
00281 
00282     s.cancel(&intr);
00283 }
00284 
00285 
00286 void
00287 BackoffTimer::resume(double difs)
00288 {
00289     Scheduler &s = Scheduler::instance();
00290 
00291     assert(busy_ && paused_);
00292 
00293     paused_ = 0;
00294     stime = s.clock();
00295 
00296     /*
00297      * The media should be idle for DIFS time before we start
00298      * decrementing the counter, so I add difs time in here.
00299      */
00300     difs_wait = difs;
00301     /*
00302 #ifdef USE_SLOT_TIME
00303     ROUND_TIME();
00304 #endif
00305     */
00306     assert(rtime + difs_wait >= 0.0);
00307         s.schedule(this, &intr, rtime + difs_wait);
00308 }
00309 
00310 

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