• Main Page
  • Classes
  • Files
  • File List

/Users/yzchen/ns/ns-allinone-2.33/ns-2.33/common/scheduler.h

00001 /* -*-  Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
00002 /*
00003  * Copyright (c) 1994 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  * @(#) $Header: /cvsroot/nsnam/ns-2/common/scheduler.h,v 1.28 2007/12/04 19:59:31 seashadow Exp $ (LBL)
00035  */
00036 
00037 #ifndef ns_scheduler_h
00038 #define ns_scheduler_h
00039 
00040 #include "config.h"
00041 
00042 // Make use of 64 bit integers if available.
00043 #ifdef HAVE_INT64
00044 typedef int64_t scheduler_uid_t;
00045 #define UID_PRINTF_FORMAT STRTOI64_FMTSTR
00046 #define STRTOUID(S) STRTOI64((S), NULL, 0)
00047 #else
00048 typedef int scheduler_uid_t;
00049 #define UID_PRINTF_FORMAT "%d"
00050 #define STRTOUID(S) atoi((S))
00051 #endif
00052 
00053 
00054 class Handler;
00055 
00056 class Event {
00057 public:
00058         Event* next_;           /* event list */
00059         Event* prev_;
00060         Handler* handler_;      /* handler to call when event ready */
00061         double time_;           /* time at which event is ready */
00062         scheduler_uid_t uid_;   /* unique ID */
00063         Event() : time_(0), uid_(0) {}
00064 };
00065 
00066 /*
00067  * The base class for all event handlers.  When an event's scheduled
00068  * time arrives, it is passed to handle which must consume it.
00069  * i.e., if it needs to be freed it, it must be freed by the handler.
00070  */
00071 class Handler {
00072  public:
00073         virtual ~Handler () {}
00074         virtual void handle(Event* event) = 0;
00075 };
00076 
00077 #define SCHED_START     0.0     /* start time (secs) */
00078 
00079 class Scheduler : public TclObject {
00080 public:
00081         static Scheduler& instance() {
00082                 return (*instance_);            // general access to scheduler
00083         }
00084         void schedule(Handler*, Event*, double delay);  // sched later event
00085         virtual void run();                     // execute the simulator
00086         virtual void cancel(Event*) = 0;        // cancel event
00087         virtual void insert(Event*) = 0;        // schedule event
00088         virtual Event* lookup(scheduler_uid_t uid) = 0; // look for event
00089         virtual Event* deque() = 0;             // next event (removes from q)
00090         virtual const Event* head() = 0;        // next event (not removed from q)
00091         double clock() const {                  // simulator virtual time
00092                 return (clock_);
00093         }
00094         virtual void sync() {};
00095         virtual double start() {                // start time
00096                 return SCHED_START;
00097         }
00098         virtual void reset();
00099 protected:
00100         void dumpq();   // for debug: remove + print remaining events
00101         void dispatch(Event*);  // execute an event
00102         void dispatch(Event*, double);  // exec event, set clock_
00103         Scheduler();
00104         virtual ~Scheduler();
00105         int command(int argc, const char*const* argv);
00106         double clock_;
00107         int halted_;
00108         static Scheduler* instance_;
00109         static scheduler_uid_t uid_;
00110 };
00111 
00112 class ListScheduler : public Scheduler {
00113 public:
00114         ListScheduler() : queue_(0) {}
00115         void cancel(Event*);
00116         void insert(Event*);
00117         Event* deque();
00118         const Event* head() { return queue_; }
00119         Event* lookup(scheduler_uid_t uid);
00120 
00121 protected:
00122         Event* queue_;
00123 };
00124 
00125 #include "heap.h"
00126 
00127 class HeapScheduler : public Scheduler {
00128 public:
00129         HeapScheduler() { hp_ = new Heap; } 
00130         void cancel(Event* e) {
00131                 if (e->uid_ <= 0)
00132                         return;
00133                 e->uid_ = - e->uid_;
00134                 hp_->heap_delete((void*) e);
00135         }
00136         void insert(Event* e) {
00137                 hp_->heap_insert(e->time_, (void*) e);
00138         }
00139         Event* lookup(scheduler_uid_t uid);
00140         Event* deque();
00141         const Event* head() { return (const Event *)hp_->heap_min(); }
00142 protected:
00143         Heap* hp_;
00144 };
00145 
00146 class CalendarScheduler : public Scheduler {
00147 public:
00148         CalendarScheduler();
00149         ~CalendarScheduler();
00150         void cancel(Event*);
00151         void insert(Event*);
00152         Event* lookup(scheduler_uid_t uid);
00153         Event* deque();
00154         const Event* head();
00155 
00156 protected:
00157         double min_bin_width_;          // minimum bin width for Calendar Queue
00158         unsigned int adjust_new_width_interval_; // The interval (in unit of resize time) for adjustment of bin width. A zero value disables automatic bin width adjustment
00159         unsigned time_to_newwidth;      // how many time we failed to adjust the width based on snoopy-queue
00160         long unsigned head_search_;
00161         long unsigned insert_search_;
00162         int round_num_;
00163         long int gap_num_;              //the number of gap samples in this window (in process of calculation)
00164         double last_time_;              //the departure time of first event in this window
00165         double avg_gap_;                //the average gap in last window (finished calculation)
00166 
00167         double width_;
00168         double diff0_, diff1_, diff2_; /* wrap-around checks */
00169 
00170         int stat_qsize_;                /* # of distinct priorities in queue*/
00171         int nbuckets_;
00172         int lastbucket_;
00173         int top_threshold_;
00174         int bot_threshold_;
00175 
00176         struct Bucket {
00177                 Event *list_;
00178                 int    count_;
00179         } *buckets_;
00180                 
00181         int qsize_;
00182 
00183         virtual void reinit(int nbuck, double bwidth, double start);
00184         virtual void resize(int newsize, double start);
00185         virtual double newwidth(int newsize);
00186 
00187 private:
00188         virtual void insert2(Event*);
00189         double cal_clock_;  // same as clock in sims, may be different in RT-scheduling.
00190 
00191 };
00192 
00193 class SplayScheduler : public Scheduler 
00194 {
00195 public:
00196         SplayScheduler() : root_(0), qsize_(0) {}
00197         void insert(Event *);
00198         Event *deque();
00199         const Event *head();
00200         void cancel(Event *);
00201         Event *lookup(scheduler_uid_t);
00202 
00203         //void validate() { assert(validate(root_) == qsize_); };
00204     
00205 protected:
00206         /* XXX even if debug is enabled, we want these inlined, so
00207            XXX they are defined as macros in splay-scheduler.cc
00208            Event *&LEFT(Event *e)  { return e->prev_; }
00209            Event *&RIGHT(Event *e) { return e->next_; }
00210         */
00211         Event *uid_lookup(Event *);
00212 
00213         Event                   *root_;
00214         scheduler_uid_t         lookup_uid_;
00215         int                     qsize_;
00216 private:
00217         int validate(Event *);
00218 };
00219 
00220 
00221 #endif

Generated on Tue Aug 10 2010 16:16:06 for ns-2.33 by  doxygen 1.7.1