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 |