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

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

Generated on Tue Apr 20 12:14:23 2004 for NS2.26SourcesOriginal by doxygen 1.3.3