src/core/model/synchronizer.h
changeset 11131 6a448ac28669
parent 11045 6024c150e4c8
child 11531 5d6b3f94ebf3
equal deleted inserted replaced
11130:3f9a0f5f0be6 11131:6a448ac28669
    21 
    21 
    22 #include <stdint.h>
    22 #include <stdint.h>
    23 #include "nstime.h"
    23 #include "nstime.h"
    24 #include "object.h"
    24 #include "object.h"
    25 
    25 
       
    26 /**
       
    27  * \file
       
    28  * \ingroup realtime
       
    29  * ns3::Synchronizer declaration.
       
    30  */
       
    31 
    26 namespace ns3 {
    32 namespace ns3 {
    27 
    33 
    28 /**
    34 /**
       
    35  * @ingroup realtime
    29  * @brief Base class used for synchronizing the simulation events to some
    36  * @brief Base class used for synchronizing the simulation events to some
    30  * real time "wall clock."
    37  * real time "wall clock."
    31  *
    38  *
    32  * The simulation clock is maintained as a 64-bit integer in a unit specified
    39  * The simulation clock is maintained as a 64-bit integer in a unit specified
    33  * by the user through the TimeStepPrecision::Set function. This means that
    40  * by the user through the Time::SetResolution function. This means that
    34  * it is not possible to specify event expiration times with anything better
    41  * it is not possible to specify event expiration times with anything better
    35  * than this user-specified accuracy.  We use this clock for the simulation
    42  * than this user-specified accuracy.  We use this clock for the simulation
    36  * time.
    43  * time.
    37  *
    44  *
    38  * The real-time clock is maintained as a 64-bit integer count of nanoseconds.
    45  * The real-time clock is maintained as a 64-bit integer count of nanoseconds.
    42  * feedback loop.
    49  * feedback loop.
    43  */
    50  */
    44 class Synchronizer : public Object 
    51 class Synchronizer : public Object 
    45 {
    52 {
    46 public:
    53 public:
       
    54   /**
       
    55    * Get the registered TypeId for this class.
       
    56    * \returns The TypeId.
       
    57    */
    47   static TypeId GetTypeId (void);
    58   static TypeId GetTypeId (void);
    48 
    59 
       
    60   /** Constructor. */
    49   Synchronizer ();
    61   Synchronizer ();
       
    62   /** Destructor. */
    50   virtual ~Synchronizer ();
    63   virtual ~Synchronizer ();
    51 
    64 
    52 /**
    65   /**
    53  * @brief Return true if this synchronizer is actually synchronizing to a
    66    * @brief Return true if this synchronizer is actually synchronizing to a
    54  * realtime clock.  The simulator sometimes needs to know this.
    67    * realtime clock.
    55  * @returns True if locked with realtime, false if not.
    68    *
    56  */
    69    * The simulator sometimes needs to know this.
       
    70    *
       
    71    * @returns \c true if locked with realtime, \c false if not.
       
    72    */
    57   bool Realtime (void);
    73   bool Realtime (void);
    58 
    74 
    59 /**
    75   /**
    60  * @brief Retrieve the value of the origin of the underlying normalized wall
    76    * @brief Retrieve the value of the origin of the underlying normalized wall
    61  * clock time in simulator timestep units.
    77    * clock time in simulator timestep units.
    62  *
    78    *
    63  * @returns The normalized wall clock time (in simulator timestep units).
    79    * @returns The normalized wall clock time (in Time resolution units).
    64  * @see TimeStepPrecision::Get
    80    * @see SetOrigin
    65  * @see Synchronizer::SetOrigin
    81    */
    66  */
       
    67   uint64_t GetCurrentRealtime (void);
    82   uint64_t GetCurrentRealtime (void);
    68 
    83 
    69 /**
    84   /**
    70  * @brief Establish a correspondence between a simulation time and the
    85    * @brief Establish a correspondence between a simulation time and the
    71  * synchronizer real time.
    86    * synchronizer real time.
    72  *
    87    *
    73  * This method is expected to be called at the "instant" before simulation
    88    * This method is expected to be called at the "instant" before simulation
    74  * begins.  At this point, simulation time = 0, and a 
    89    * begins.  At this point, simulation time = 0, and a 
    75  * set = 0 in this method.  We then associate this time with the current
    90    * set = 0 in this method.  We then associate this time with the current
    76  * value of the real time clock that will be used to actually perform the
    91    * value of the real time clock that will be used to actually perform the
    77  * synchronization.
    92    * synchronization.
    78  *
    93    *
    79  * Subclasses are expected to implement the corresponding DoSetOrigin pure
    94    * Subclasses are expected to implement the corresponding DoSetOrigin pure
    80  * virtual method to do the actual real-time-clock-specific work of making the 
    95    * virtual method to do the actual real-time-clock-specific work
    81  * correspondence mentioned above.
    96    * of making the correspondence mentioned above.
    82  *
    97    *
    83  * @param ts The simulation time we should use as the origin (in simulator
    98    * @param ts The simulation time we should use as the origin (in
    84  * timestep units).
    99    *     Time resolution units).
    85  * @see TimeStepPrecision::Get
   100    * @see DoSetOrigin
    86  * @see TimeStepPrecision::DoSetOrigin
   101    */
    87  */
       
    88   void SetOrigin (uint64_t ts);
   102   void SetOrigin (uint64_t ts);
    89 
   103 
    90 /**
   104   /**
    91  * @brief Retrieve the value of the origin of the simulation time in 
   105    * @brief Retrieve the value of the origin of the simulation time in 
    92  * simulator timestep units.
   106    * Time.resolution units.
    93  *
   107    *
    94  * @returns The simulation time used as the origin (in simulator timestep
   108    * @returns The simulation time used as the origin (in Time resolution units).
    95  * units).
   109    * @see SetOrigin
    96  * @see TimeStepPrecision::Get
   110    */
    97  * @see Synchronizer::SetOrigin
       
    98  */
       
    99   uint64_t GetOrigin (void);
   111   uint64_t GetOrigin (void);
   100 
   112 
   101 /**
   113   /**
   102  * @brief Retrieve the difference between the real time clock used to 
   114    * @brief Retrieve the difference between the real time clock used to 
   103  * synchronize the simulation and the simulation time (in simulator timestep
   115    * synchronize the simulation and the simulation time (in
   104  * units).
   116    * Time resolution units).
   105  *
   117    *
   106  * @param ts Simulation timestep from the simulator interpreted as current time
   118    * @param ts Simulation time in Time resolution units.
   107  * in the simulator.
   119    * @returns Simulation Time (in Time resolution units)
   108  * @returns Simulation timestep (in simulator timestep units) minus origin 
   120    *     minus the origin time (stored internally in nanosecond units).
   109  * time (stored internally in nanosecond units).
   121    * @see SetOrigin
   110  * @see TimeStepPrecision::Get
   122    * @see DoGetDrift
   111  * @see Synchronizer::SetOrigin
   123    */
   112  * @see Synchronizer::DoGetDrift
       
   113  */
       
   114   int64_t GetDrift (uint64_t ts);
   124   int64_t GetDrift (uint64_t ts);
   115 
   125 
   116 /**
   126   /**
   117  * @brief Wait until the real time is in sync with the specified simulation
   127    * @brief Wait until the real time is in sync with the specified simulation
   118  * time or until the synchronizer is Sigalled.
   128    * time or until the synchronizer is Sigalled.
   119  *
   129    *
   120  * This is where the real work of synchronization is done.  The Time passed
   130    * This is where the real work of synchronization is done.  The \c tsCurrent
   121  * in as a parameter is the simulation time.  The job of Synchronize is to
   131    * argument is the simulation time.  The job of Synchronize is to
   122  * translate from simulation time to synchronizer time (in a perfect world
   132    * translate from simulation time to synchronizer time (in a perfect world
   123  * this is the same time) and then figure out how long in real-time it needs
   133    * this is the same time) and then figure out how long in real-time it needs
   124  * to wait until that synchronizer / simulation time comes around.
   134    * to wait until that synchronizer / simulation time comes around.
   125  *
   135    *
   126  * Subclasses are expected to implement the corresponding DoSynchronize pure
   136    * Subclasses are expected to implement the corresponding DoSynchronize pure
   127  * virtual method to do the actual real-time-clock-specific work of waiting 
   137    * virtual method to do the actual real-time-clock-specific work of waiting 
   128  * (either busy-waiting or sleeping, or some combination thereof) until the
   138    * (either busy-waiting or sleeping, or some combination thereof) until the
   129  * requested simulation time.
   139    * requested simulation time.
   130  *
   140    *
   131  * @param tsCurrent The current simulation time (in simulator timestep units).
   141    * @param tsCurrent The current simulation time (in Time resolution units).
   132  * @param tsDelay The simulation time we need to wait for (in simulator
   142    * @param tsDelay The simulation time we need to wait for (in Time
   133  * timestep units).
   143    *     resolution units).
   134  * @returns True if the function ran to completion, false if it was interrupted
   144    * @returns \c true if the function ran to completion,
   135  * by a Signal.
   145    *          \c false if it was interrupted by a Signal.
   136  * @see TimeStepPrecision::Get
   146    * @see DoSynchronize
   137  * @see Synchronizer::DoSynchronize
   147    * @see Signal
   138  * @see Synchronizer::Signal
   148    */
   139  */
       
   140   bool Synchronize (uint64_t tsCurrent, uint64_t tsDelay);
   149   bool Synchronize (uint64_t tsCurrent, uint64_t tsDelay);
   141 
   150 
   142 /**
   151   /**
   143  * @brief Tell a possible simulator thread waiting in the Synchronize method
   152    * @brief Tell a possible simulator thread waiting in the Synchronize method
   144  * that an event has happened which demands a reevaluation of the wait time.
   153    * that an event has happened which demands a reevaluation of the wait time.
   145  * This will cause the thread to wake and return to the simulator proper
   154    *
   146  * where it can get its bearings.
   155    * This will cause the thread to wake and return to the simulator proper
   147  *
   156    * where it can get its bearings.
   148  * @see Synchronizer::Synchronize
   157    *
   149  * @see Synchronizer::DoSignal
   158    * @see Synchronize
   150  */
   159    * @see DoSignal
       
   160    */
   151   void Signal (void);
   161   void Signal (void);
   152 
   162 
   153 /**
   163   /**
   154  * @brief Set the condition variable that tells a possible simulator thread 
   164    * @brief Set the condition variable that tells a possible simulator thread 
   155  * waiting in the Synchronize method that an event has happened which demands
   165    * waiting in the Synchronize method that an event has happened which demands
   156  * a reevaluation of the wait time.
   166    * a reevaluation of the wait time.
   157  *
   167    *
   158  * @see Synchronizer::Signal
   168    * @see Signal
   159  */
   169    */
   160   void SetCondition (bool);
   170   void SetCondition (bool);
   161 
   171 
   162 /**
   172   /**
   163  * @brief Ask the synchronizer to remember what time it is.  Typically used
   173    * @brief Ask the synchronizer to remember what time it is.
   164  * with EventEnd to determine the real execution time of a simulation event.
   174    *
   165  *
   175    * Typically used with EventEnd to determine the real execution time
   166  * @see Synchronizer::EventEnd
   176    * of a simulation event.
   167  * @see TimeStepPrecision::Get
   177    *
   168  */
   178    * @see EventEnd
       
   179    */
   169   void EventStart (void);
   180   void EventStart (void);
   170 
   181 
   171 /**
   182   /**
   172  * @brief Ask the synchronizer to return the time step between the instant
   183    * @brief Ask the synchronizer to return the time step between the instant
   173  * remembered during EventStart and now.  Used in conjunction with EventStart
   184    * remembered during EventStart and now.
   174  * to determine the real execution time of a simulation event.
   185    *
   175  *
   186    * Used in conjunction with EventStart to determine the real execution time
   176  * @see Synchronizer::EventStart
   187    * of a simulation event.
   177  * @see TimeStepPrecision::Get
   188    *
   178  */
   189    * @returns The elapsed real time, in ns.
       
   190    * @see EventStart
       
   191    */
   179   uint64_t EventEnd (void);
   192   uint64_t EventEnd (void);
   180 
   193 
   181 protected:
   194 protected:
   182 /**
   195   /**
   183  * @brief Establish a correspondence between a simulation time and a 
   196    * @brief Establish a correspondence between a simulation time and a 
   184  * wall-clock (real) time.
   197    * wall-clock (real) time.
   185  *
   198    *
   186  * There are three timelines involved here:  the simulation time, the 
   199    * There are three timelines involved here:  the simulation (virtual) time,
   187  * (absolute) wall-clock time and the (relative) synchronizer real time.
   200    * the (absolute) wall-clock time and the (relative) synchronizer real time.
   188  * Calling this method makes a correspondence between the origin of the
   201    * Calling this method makes a correspondence between the origin of the
   189  * synchronizer time and the current wall-clock time.
   202    * synchronizer time and the current wall-clock time.
   190  *
   203    *
   191  * This method is expected to be called at the "instant" before simulation
   204    * This method is expected to be called at the "instant" before simulation
   192  * begins.  At this point, simulation time = 0, and synchronizer time is
   205    * begins.  At this point, simulation time = 0, and synchronizer time is
   193  * set = 0 in this method.  We then associate this time with the current
   206    * set = 0 in this method.  We then associate this time with the current
   194  * value of the real time clock that will be used to actually perform the
   207    * value of the real time clock that will be used to actually perform the
   195  * synchronization.
   208    * synchronization.
   196  *
   209    *
   197  * Subclasses are expected to implement this method to do the actual 
   210    * Subclasses are expected to implement this method to do the actual 
   198  * real-time-clock-specific work of making the correspondence mentioned above.
   211    * real-time-clock-specific work of making the correspondence mentioned above.
   199  * for example, this is where the differences between Time parameters and
   212    * for example, this is where the differences between Time parameters and
   200  * parameters to clock_nanosleep would be dealt with. 
   213    * parameters to clock_nanosleep would be dealt with. 
   201  *
   214    *
   202  * @param ns The simulation time we need to use as the origin (normalized to
   215    * @param ns The simulation time we need to use as the origin (normalized to
   203  * nanosecond units).
   216    *    nanosecond units).
   204  * @see Synchronizer::SetOrigin
   217    * @see SetOrigin
   205  * @see TimeStepPrecision::Get
   218    */
   206  */
       
   207   virtual void DoSetOrigin (uint64_t ns) = 0;
   219   virtual void DoSetOrigin (uint64_t ns) = 0;
   208 
   220 
   209 /**
   221   /**
   210  * @brief Return true if this synchronizer is actually synchronizing to a
   222    * @brief Return \c true if this synchronizer is actually synchronizing to a
   211  * realtime clock.  The simulator sometimes needs to know this.
   223    * realtime clock.
   212  *
   224    *
   213  * Subclasses are expected to implement this method to tell the outside world
   225    * The simulator sometimes needs to know this.
   214  * whether or not they are synchronizing to a realtime clock.
   226    *
   215  *
   227    * Subclasses are expected to implement this method to tell the outside world
   216  * @returns True if locked with realtime, false if not.
   228    * whether or not they are synchronizing to a realtime clock.
   217  */
   229    *
       
   230    * @returns \c true if locked with realtime, \c false if not.
       
   231    */
   218   virtual bool DoRealtime (void) = 0;
   232   virtual bool DoRealtime (void) = 0;
   219 
   233 
   220 /**
   234   /**
   221  * @brief Retrieve the value of the origin of the underlying normalized wall
   235    * @brief Retrieve the value of the origin of the underlying normalized wall
   222  * clock time in simulator timestep units.
   236    * clock time in Time resolution units.
   223  *
   237    *
   224  * Subclasses are expected to implement this method to do the actual
   238    * Subclasses are expected to implement this method to do the actual
   225  * real-time-clock-specific work of getting the current time.
   239    * real-time-clock-specific work of getting the current time.
   226  *
   240    *
   227  * @returns The normalized wall clock time (in nanosecond units).
   241    * @returns The normalized wall clock time (in nanosecond units).
   228  * @see TimeStepPrecision::Get
   242    * @see SetOrigin
   229  * @see Synchronizer::SetOrigin
   243    */
   230  */
       
   231   virtual uint64_t DoGetCurrentRealtime (void) = 0;
   244   virtual uint64_t DoGetCurrentRealtime (void) = 0;
   232 
   245 
   233 /**
   246   /**
   234  * @brief Wait until the real time is in sync with the specified simulation
   247    * @brief Wait until the real time is in sync with the specified simulation
   235  * time.
   248    * time.
   236  *
   249    *
   237  * This is where the real work of synchronization is done.  The Time passed
   250    * This is where the real work of synchronization is done.  The
   238  * in as a parameter is the simulation time.  The job of Synchronize is to
   251    * \c nsCurrent argument is the simulation time (in ns).  The job of
   239  * translate from simulation time to synchronizer time (in a perfect world
   252    * DoSynchronize is to translate from simulation time to synchronizer time
   240  * this is the same time) and then figure out how long in real-time it needs
   253    * (in a perfect world these are the same time) and then figure out
   241  * to wait until that synchronizer / simulation time comes around.
   254    * how long in real-time it needs to wait until that
   242  *
   255    * synchronizer / simulation time comes around.
   243  * Subclasses are expected to implement this method to do the actual
   256    *
   244  * real-time-clock-specific work of waiting (either busy-waiting or sleeping,
   257    * Subclasses are expected to implement this method to do the actual
   245  * or some combination) until the requested simulation time.
   258    * real-time-clock-specific work of waiting (either busy-waiting or sleeping,
   246  *
   259    * or some combination) until the requested simulation time.
   247  * @param nsCurrent The current simulation time (normalized to nanosecond
   260    *
   248  * units).
   261    * @param nsCurrent The current simulation time (in nanosecond units).
   249  * @param nsDelay The simulation time we need to wait for (normalized to 
   262    * @param nsDelay The simulation time we need to wait for (normalized to 
   250  * nanosecond units).
   263    * nanosecond units).
   251  * @returns True if the function ran to completion, false if it was interrupted
   264    * @returns \c true if the function ran to completion,
   252  * by a Signal.
   265    *          \c false if it was interrupted by a Signal.
   253  * @see Synchronizer::Synchronize
   266    * @see Synchronize
   254  * @see TimeStepPrecision::Get
   267    * @see Signal
   255  * @see Synchronizer::Signal
   268    */
   256  */
       
   257   virtual bool DoSynchronize (uint64_t nsCurrent, uint64_t nsDelay) = 0;
   269   virtual bool DoSynchronize (uint64_t nsCurrent, uint64_t nsDelay) = 0;
   258 
   270 
   259 /**
   271   /**
   260  * @brief Declaration of the method used to tell a possible simulator thread 
   272    * @brief Tell a possible simulator thread waiting in the
   261  * waiting in the DoSynchronize method that an event has happened which
   273    * DoSynchronize method that an event has happened which
   262  * demands a reevaluation of the wait time.
   274    * demands a reevaluation of the wait time.
   263  *
   275    *
   264  * @see Synchronizer::Signal
   276    * @see Signal
   265  */
   277    */
   266   virtual void DoSignal (void) = 0;
   278   virtual void DoSignal (void) = 0;
   267 
   279 
   268 /**
   280   /**
   269  * @brief Declaration of the method used to set the condition variable that 
   281    * @brief Set the condition variable to tell a possible simulator thread
   270  * tells a possible simulator thread waiting in the Synchronize method that an
   282    * waiting in the Synchronize method that an event has happened which
   271  * event has happened which demands a reevaluation of the wait time.
   283    * demands a reevaluation of the wait time.
   272  *
   284    *
   273  * @see Synchronizer::SetCondition
   285    * @see SetCondition
   274  */
   286    */
   275   virtual void DoSetCondition (bool) = 0;
   287   virtual void DoSetCondition (bool) = 0;
   276 
   288 
   277 /**
   289   /**
   278  * @brief Declaration of method used to retrieve drift between the real time
   290    * @brief Get the drift between the real time clock used to synchronize
   279  * clock used to synchronize the simulation and the current simulation time.
   291    * the simulation and the current simulation time.
   280  *
   292    *
   281  * @param ns Simulation timestep from the simulator normalized to nanosecond 
   293    * @param ns Simulation time in ns.
   282  * steps.
   294    * @returns Drift in ns units.
   283  * @returns Drift in nanosecond units.
   295    * @see SetOrigin
   284  * @see TimeStepPrecision::Get
   296    * @see GetDrift
   285  * @see Synchronizer::SetOrigin
   297    */
   286  * @see Synchronizer::GetDrift
       
   287  */
       
   288   virtual int64_t DoGetDrift (uint64_t ns) = 0;
   298   virtual int64_t DoGetDrift (uint64_t ns) = 0;
   289 
   299 
       
   300   /**
       
   301    * @brief Record the normalized real time at which the current
       
   302    * event is starting execution.
       
   303    */
   290   virtual void DoEventStart (void) = 0;
   304   virtual void DoEventStart (void) = 0;
       
   305   /**
       
   306    * @brief Return the amount of real time elapsed since the last call
       
   307    * to EventStart.
       
   308    *
       
   309    * @returns The elapsed real time, in ns.
       
   310    */
   291   virtual uint64_t DoEventEnd (void) = 0;
   311   virtual uint64_t DoEventEnd (void) = 0;
   292 
   312 
       
   313   /** The real time, in ns, when SetOrigin was called. */
   293   uint64_t m_realtimeOriginNano;
   314   uint64_t m_realtimeOriginNano;
       
   315   /** The simulation time, in ns, when SetOrigin was called. */
   294   uint64_t m_simOriginNano;
   316   uint64_t m_simOriginNano;
   295 
   317 
   296 private:
   318 private:
   297 /**
   319   /**
   298  * @brief Convert a simulator time step (which can be steps of time in a 
   320    * @brief Convert a simulator time step (in Time resolution units)
   299  * user-specified unit) to a normalized time step in nanosecond units.
   321    * to a normalized time step in nanosecond units.
   300  *
   322    *
   301  * @param ts The simulation time step to be normalized.
   323    * @param ts The simulation time step to be normalized.
   302  * @returns The simulation time step normalized to nanosecond units.
   324    * @returns The simulation time step normalized to nanosecond units.
   303  * @see TimeStepPrecision::Get
   325    */
   304  */
       
   305   uint64_t TimeStepToNanosecond (uint64_t ts);
   326   uint64_t TimeStepToNanosecond (uint64_t ts);
   306 
   327 
   307 /**
   328   /**
   308  * @brief Convert a normalized nanosecond count into a simulator time step
   329    * @brief Convert a normalized nanosecond time step into a
   309  * (which can be steps of time in a user-specified unit).
   330    * simulator time step (in Time resolution units).
   310  *
   331    *
   311  * @param ns The nanosecond count step to be converted
   332    * @param ns The nanosecond count step to be converted
   312  * @returns The simulation time step to be interpreted in appropriate units.
   333    * @returns The simulation time step to be interpreted in appropriate units.
   313  * @see TimeStepPrecision::Get
   334    */
   314  */
       
   315   uint64_t NanosecondToTimeStep (uint64_t ns);
   335   uint64_t NanosecondToTimeStep (uint64_t ns);
   316 };
   336 };
   317 
   337 
   318 } // namespace ns3
   338 } // namespace ns3
   319 
   339