mrcl_mac-timers.cc

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 <mrcl_mac-timers.h>
00050 #include <miracle_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 MrclMacTimer::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 MrclMacTimer::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 MrclDeferTimer::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 MrclDeferTimer::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 MrclNavTimer::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 MrclRxTimer::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 MrclTxTimer::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 MrclIFTimer::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 MrclBackoffTimer::handle(Event *)
00214 {
00215         busy_ = 0;
00216         paused_ = 0;
00217         stime = 0.0;
00218         rtime = 0.0;
00219         difs_wait = 0.0;
00220         mac->backoffHandler();
00221 }
00222 
00223 void
00224 MrclBackoffTimer::start(int cw, int idle, double difs)
00225 {
00226         Scheduler &s = Scheduler::instance();
00227 
00228         assert(busy_ == 0);
00229 
00230         busy_ = 1;
00231         paused_ = 0;
00232         stime = s.clock();
00233         
00234         rtime = (Random::random() % cw) * mac->phymib_.getSlotTime();
00235 
00236 
00237 
00238 #ifdef USE_SLOT_TIME
00239         ROUND_TIME();
00240 #endif
00241         difs_wait = difs;
00242 
00243         if(idle == 0)
00244                 paused_ = 1;
00245         else {
00246                 assert(rtime + difs_wait >= 0.0);
00247                 s.schedule(this, &intr, difs_wait);
00248         }
00249 }
00250 
00251 
00252 void
00253 MrclBackoffTimer::pause()
00254 {
00255         Scheduler &s = Scheduler::instance();
00256 
00257         //the caculation below make validation pass for linux though it
00258         // looks dummy
00259 
00260         double st = s.clock();
00261         double rt = stime + difs_wait;
00262         double sr = st - rt;
00263         double mst = (mac->phymib_.getSlotTime());
00264 
00265 
00266 
00267         int slots = int (sr/mst);
00268 
00269         if(slots < 0)
00270                 slots = 0;
00271         assert(busy_ && ! paused_);
00272 
00273         paused_ = 1;
00274         rtime -= (slots * mac->phymib_.getSlotTime());
00275 
00276 
00277         assert(rtime >= 0.0);
00278 
00279         difs_wait = 0.0;
00280 
00281         s.cancel(&intr);
00282 }
00283 
00284 
00285 void
00286 MrclBackoffTimer::resume(double difs)
00287 {
00288         Scheduler &s = Scheduler::instance();
00289 
00290         assert(busy_ && paused_);
00291 
00292         paused_ = 0;
00293         stime = s.clock();
00294 
00295         /*
00296          * The media should be idle for DIFS time before we start
00297          * decrementing the counter, so I add difs time in here.
00298          */
00299         difs_wait = difs;
00300         /*
00301 #ifdef USE_SLOT_TIME
00302         ROUND_TIME();
00303 #endif
00304         */
00305         assert(rtime + difs_wait >= 0.0);
00306         s.schedule(this, &intr, rtime + difs_wait);
00307 }
00308 
00309 

Generated on Wed Nov 26 15:47:28 2008 for NS-MIRACLE library by  doxygen 1.5.2