simulator.h

Go to the documentation of this file.
00001 // Define the event scheduler for IAASim
00002 // George F. Riley, Georgia Tech, Summer 2009
00003 
00004 // This scheduler is loosely based on the event scheduler found in ns-3.
00005 // The design is such that any function, either a global static function
00006 // or a member function on an object can be the event handler. Further
00007 // the handler function can have arbitrary parameter types.  This implementation
00008 // defines functions with up to four arguments.  Should the need arise
00009 // it is easy to add longer argument lists.
00010 
00011 #ifndef __SIMULATOR_H__
00012 #define __SIMULATOR_H__
00013 
00014 #include <set>
00015 #include <map>
00016 #include "component.h"
00017 
00018 class Component;
00019 
00020 // First define the base class Event, then the events with up
00021 // to four templated parameters.
00022 
00023 // Define the base event class
00024 class EventBase 
00025 {
00026  public:
00027   EventBase(double t) : time(t), uid(nextUID++) {}
00028     EventBase(double t, int u) : time(t), uid(u) {}
00029       virtual void CallHandler() = 0;  // All subclasses must implement CallHandler
00030  public:
00031       double time;   // Timestamp for the event
00032       int    uid;    // Each event has a unique identifier to break timestamp ties
00033       static int nextUID;
00034  private:
00035 };
00036 
00037 // Define an EventID class that is the return type from all schedule
00038 // functions.  This is used to cancel the event
00039 class EventId : public EventBase
00040 {
00041 public:
00042   EventId(double t, int u) : EventBase(t, u) {}
00043   void CallHandler() {}
00044 };
00045 
00046 // Define the variable parameter list Event objects  
00047 template<typename T, typename OBJ>
00048 class Event0 : public EventBase
00049 {
00050 public:
00051   Event0(double t, void (T::*f)(void), OBJ* obj0)
00052     : EventBase(t), handler(f), obj(obj0){}
00053   void (T::*handler)(void);
00054   OBJ*      obj;
00055 public:
00056   void CallHandler();
00057 };
00058 
00059 template <typename T, typename OBJ>
00060 void Event0<T, OBJ>::CallHandler()
00061 {
00062   (obj->*handler)();
00063 }
00064 
00065 template<typename T, typename OBJ, typename U1, typename T1>
00066 class Event1 : public EventBase
00067 {
00068 public:
00069   Event1(double t, void (T::*f)(U1), OBJ* obj0, T1 t1_0)
00070     : EventBase(t), handler(f), obj(obj0), t1(t1_0){}
00071   void (T::*handler)(U1);
00072   OBJ*      obj;
00073   T1        t1;
00074 public:
00075   void CallHandler();
00076 };
00077 
00078 template <typename T, typename OBJ, typename U1, typename T1>
00079 void Event1<T, OBJ, U1, T1>::CallHandler()
00080 {
00081   (obj->*handler)(t1);
00082 }
00083 
00084 template<typename T, typename OBJ,
00085          typename U1, typename T1, 
00086          typename U2, typename T2>
00087 class Event2 : public EventBase
00088 {
00089 public:
00090   Event2(double t, void (T::*f)(U1, U2), OBJ* obj0, T1 t1_0, T2 t2_0)
00091     : EventBase(t), handler(f), obj(obj0), t1(t1_0), t2(t2_0) {}
00092   void (T::*handler)(U1, U2);
00093   OBJ*      obj;
00094   T1        t1;
00095   T2        t2;
00096 public:
00097   void CallHandler();
00098 };
00099 
00100 template <typename T, typename OBJ, 
00101           typename U1, typename T1,
00102           typename U2, typename T2>
00103 void Event2<T, OBJ, U1, T1, U2, T2>::CallHandler()
00104 {
00105   (obj->*handler)(t1, t2);
00106 }
00107 
00108 template <typename T,  typename OBJ,
00109           typename U1, typename T1,
00110           typename U2, typename T2,
00111           typename U3, typename T3>
00112 class Event3 : public EventBase {
00113 public:
00114    Event3(double t, void (T::*f)(U1, U2, U3), OBJ *obj0, T1 t1_0, T2 t2_0, T3 t3_0)  
00115      : EventBase(t), handler(f), obj(obj0), t1(t1_0), t2(t2_0), t3(t3_0) {}
00116    void (T::*handler)(U1, U2, U3);
00117    OBJ* obj;
00118    T1 t1;
00119    T2 t2;
00120    T3 t3;
00121    
00122 public:
00123    void CallHandler();
00124 };
00125 
00126 template <typename T,  typename OBJ,
00127           typename U1, typename T1,
00128           typename U2, typename T2,
00129           typename U3, typename T3> 
00130 void Event3<T,OBJ,U1,T1,U2,T2,U3,T3>::CallHandler() {
00131      (obj->*handler)(t1,t2,t3);
00132 }
00133 
00134 template <typename T,  typename OBJ,
00135           typename U1, typename T1,
00136           typename U2, typename T2,
00137           typename U3, typename T3,
00138           typename U4, typename T4>
00139 class Event4 : public EventBase {
00140 public:
00141    Event4(double t, void (T::*f)(U1, U2, U3, U4), OBJ *obj0, T1 t1_0, T2 t2_0, T3 t3_0, T4 t4_0)  
00142      : EventBase(t), handler(f), obj(obj0), t1(t1_0), t2(t2_0), t3(t3_0), t4(t4_0){}
00143    void (T::*handler)(U1, U2, U3, U4);
00144    OBJ* obj;
00145    T1 t1;
00146    T2 t2;
00147    T3 t3;
00148    T4 t4;
00149    
00150 public:
00151    void CallHandler();
00152 };
00153 
00154 template <typename T,  typename OBJ,
00155           typename U1, typename T1,
00156           typename U2, typename T2,
00157           typename U3, typename T3,
00158           typename U4, typename T4> 
00159 void Event4<T,OBJ,U1,T1,U2,T2,U3,T3,U4,T4>::CallHandler() {
00160      (obj->*handler)(t1,t2,t3,t4);
00161 }
00162 
00163 
00164 // Create events that call static functions rather then
00165 // rather than object member functions
00166 // Also need a variant of the Event0 that calls a static function,
00167 // not a member function.
00168 class Event0Stat : public EventBase
00169 {
00170 public:
00171   Event0Stat(double t, void (*f)(void))
00172     : EventBase(t), handler(f){}
00173   void (*handler)(void);
00174 public:
00175   void CallHandler();
00176 };
00177 
00178 template<typename U1, typename T1>
00179 class Event1Stat : public EventBase
00180 {
00181 public:
00182   Event1Stat(double t, void (*f)(U1), T1 t1_0)
00183     : EventBase(t), handler(f), t1(t1_0){}
00184   void (*handler)(U1);
00185   T1        t1;
00186 public:
00187   void CallHandler();
00188 };
00189 
00190 template <typename U1, typename T1>
00191 void Event1Stat<U1, T1>::CallHandler()
00192 {
00193   handler(t1);
00194 }
00195 
00196 
00197 template<typename U1, typename T1, 
00198          typename U2, typename T2>
00199 class Event2Stat : public EventBase
00200 {
00201 public:
00202   Event2Stat(double t, void (*f)(U1, U2), T1 t1_0, T2 t2_0)
00203     : EventBase(t), handler(f), t1(t1_0), t2(t2_0) {}
00204   void (*handler)(U1, U2);
00205   T1        t1;
00206   T2        t2;
00207 public:
00208   void CallHandler();
00209 };
00210 
00211 template <typename U1, typename T1,
00212           typename U2, typename T2>
00213 void Event2Stat<U1, T1, U2, T2>::CallHandler()
00214 {
00215   handler(t1, t2);
00216 }
00217 
00218 template <typename U1, typename T1,
00219           typename U2, typename T2,
00220           typename U3, typename T3>
00221 class Event3Stat : public EventBase {
00222 public:
00223    Event3Stat(double t, void (*f)(U1, U2, U3), T1 t1_0, T2 t2_0, T3 t3_0)  
00224      : EventBase(t), handler(f), t1(t1_0), t2(t2_0), t3(t3_0) {}
00225    void (*handler)(U1, U2, U3);
00226    T1 t1;
00227    T2 t2;
00228    T3 t3;
00229    
00230 public:
00231    void CallHandler();
00232 };
00233 
00234 template <typename U1, typename T1,
00235           typename U2, typename T2,
00236           typename U3, typename T3> 
00237 void Event3Stat<U1,T1,U2,T2,U3,T3>::CallHandler()
00238 {
00239   handler(t1,t2,t3);
00240 }
00241 
00242 template <typename U1, typename T1,
00243           typename U2, typename T2,
00244           typename U3, typename T3,
00245           typename U4, typename T4>
00246 class Event4Stat : public EventBase {
00247 public:
00248    Event4Stat(double t, void (*f)(U1, U2, U3, U4), T1 t1_0, T2 t2_0, T3 t3_0, T4 t4_0)  
00249      : EventBase(t), handler(f), t1(t1_0), t2(t2_0), t3(t3_0), t4(t4_0){}
00250    void (*handler)(U1, U2, U3, U4);
00251    T1 t1;
00252    T2 t2;
00253    T3 t3;
00254    T4 t4;
00255    
00256 public:
00257    void CallHandler();
00258 };
00259 
00260 template <typename U1, typename T1,
00261           typename U2, typename T2,
00262           typename U3, typename T3,
00263           typename U4, typename T4> 
00264 void Event4Stat<U1,T1,U2,T2,U3,T3,U4,T4>::CallHandler() {
00265      handler(t1,t2,t3,t4);
00266 }
00267 
00268 // Now define the sorted set of events and the event comparator
00269 class event_less
00270 {
00271 public:
00272   event_less() { }
00273   inline bool operator()(EventBase* const & l, const EventBase* const & r) const {
00274     if(l->time < r->time) return true;
00275     if (l->time == r->time) return l->uid < r->uid;
00276     return false;
00277   }
00278 };
00279 
00280 // Define the type for the sorted event list
00281 typedef std::set<EventBase*, event_less> EventSet_t;
00282 
00283 
00284 class ComponentDescription
00285 {
00286  public:
00287   ComponentDescription(int lp, Component* obj):lpId(lp), ptr(obj){}
00288   int lpId;
00289   Component* ptr;
00290 };
00291 
00292 //Define the type for the map of component IDs to LPs/pointers
00293 typedef std::map<int, ComponentDescription*> ComponentMap_t;
00294 
00295 // Define the simulator class.  It is implemented with only static functions
00296 class Simulator 
00297 {
00298 public:
00299   static void    Run();                 // Run the simulation
00300   static void    Stop();                // Stop the simulation
00301   static void    StopAt(double);        // Stop at the specified time
00302   static double  Now();                 // Return the current simulation time
00303   static bool    Cancel(EventId&);      // Cancel previously scheduled event
00304   static EventId Peek();                // Peek (don't remove) earliest event
00305   static EventBase* GetEarliestEvent(); // Remove and return earliest event
00306   static int     MyRank();              // Return rank number (0 if serial)
00307   // Define the templated schedule functions
00308   template <typename T, typename OBJ>
00309     static EventId Schedule(double t, void(T::*handler)(void), OBJ* obj)
00310   {
00311     EventBase* ev = new Event0<T, OBJ>(t, handler, obj);
00312     events.insert(ev);
00313     return EventId(t, ev->uid);
00314   }
00315 
00316   template <typename T, typename OBJ,
00317     typename U1, typename T1>
00318     static EventId Schedule(double t, void(T::*handler)(U1), OBJ* obj, T1 t1)
00319   {
00320     EventBase* ev = new Event1<T, OBJ, U1, T1>(t, handler, obj, t1);
00321     events.insert(ev);
00322     return EventId(t, ev->uid);
00323   }
00324 
00325   template <typename T, typename OBJ,
00326     typename U1, typename T1,
00327     typename U2, typename T2>
00328     static EventId Schedule(double t, void(T::*handler)(U1, U2), OBJ* obj, T1 t1, T2 t2)
00329   {
00330     EventBase* ev = new Event2<T, OBJ, U1, T1, U2, T2>(t, handler, obj, t1, t2);
00331     events.insert(ev);
00332     return EventId(t, ev->uid);
00333   }
00334 
00335   template <typename T, typename OBJ,
00336     typename U1, typename T1,
00337     typename U2, typename T2,
00338     typename U3, typename T3>
00339     static EventId Schedule(double t, void(T::*handler)(U1, U2, U3), OBJ* obj, T1 t1, T2 t2, T3 t3)
00340   {
00341     EventBase* ev = new Event3<T, OBJ, U1, T1, U2, T2, U3, T3>(t, handler, obj, t1, t2, t3);
00342     events.insert(ev);
00343     return EventId(t, ev->uid);
00344   }
00345 
00346   template <typename T, typename OBJ,
00347     typename U1, typename T1,
00348     typename U2, typename T2,
00349     typename U3, typename T3,
00350     typename U4, typename T4>
00351     static EventId Schedule(double t, void(T::*handler)(U1, U2, U3, U4), OBJ* obj, T1 t1, T2 t2, T3 t3, T4 t4)
00352   {
00353     EventBase* ev = new Event4<T, OBJ, U1, T1, U2, T2, U3, T3, U4, T4>(t, handler, obj, t1, t2, t3, t4);
00354     events.insert(ev);
00355     return EventId(t, ev->uid);
00356   }
00357 
00358   // Schedulers for static callback functions
00359   static EventId Schedule(double t, void(*handler)(void))
00360   {
00361     EventBase* ev = new Event0Stat(t, handler);
00362     events.insert(ev);
00363     return EventId(t, ev->uid);
00364   }
00365 
00366   template <typename U1, typename T1>
00367     static EventId Schedule(double t, void(*handler)(U1), T1 t1)
00368   {
00369     EventBase* ev = new Event1Stat<U1, T1>(t, handler, t1);
00370     events.insert(ev);
00371     return EventId(t, ev->uid);
00372   }
00373 
00374   template <typename U1, typename T1,
00375             typename U2, typename T2>
00376     static EventId Schedule(double t, void(*handler)(U1, U2), T1 t1, T2 t2)
00377   {
00378     EventBase* ev = new Event2Stat<U1, T1, U2, T2>(t, handler, t1, t2);
00379     events.insert(ev);
00380     return EventId(t, ev->uid);
00381   }
00382 
00383   template <typename U1, typename T1,
00384             typename U2, typename T2,
00385             typename U3, typename T3>
00386     static EventId Schedule(double t, void(*handler)(U1, U2, U3), T1 t1, T2 t2, T3 t3)
00387   {
00388     EventBase* ev = new Event3Stat<U1, T1, U2, T2, U3, T3>(t, handler, t1, t2, t3);
00389     events.insert(ev);
00390     return EventId(t, ev->uid);
00391   }
00392 
00393   template <typename U1, typename T1,
00394             typename U2, typename T2,
00395             typename U3, typename T3,
00396             typename U4, typename T4>
00397     static EventId Schedule(double t, void(*handler)(U1, U2, U3, U4), T1 t1, T2 t2, T3 t3, T4 t4)
00398   {
00399     EventBase* ev = new Event4Stat<U1, T1, U2, T2, U3, T3, U4, T4>(t, handler, t1, t2, t3, t4);
00400     events.insert(ev);
00401     return EventId(t, ev->uid);
00402   }
00403 
00404   static void registerComponent(Component* obj, int lp);
00405   static ComponentDescription* getComponentDesc(int);
00406 
00407 private:
00408   static EventSet_t events;
00409   static double     simTime;
00410   static ComponentMap_t components;
00411   static int nextComponentID;
00412   static int rank;
00413   static bool       halted;
00414 };
00415 
00416 #endif

Generated on Tue Oct 19 17:22:01 2010 for IRIS by  doxygen 1.5.8