source: rtems/cpukit/score/include/rtems/score/timestamp64.h @ c34bb0d

4.115
Last change on this file since c34bb0d was c34bb0d, checked in by Sebastian Huber <sebastian.huber@…>, on 06/13/12 at 09:39:43

score: Fix performance issue for 64-bit timestamps

The 64-bit timestamps were introduced to simplify the timestamp
calculations. This works well since nearly all operations are
additions. The previous _TOD_Tickle_ticks() implementation had a
serious performance regression in case of 64-bit timestamps due to the
usage of two 64-bit divisions which are quite expensive on some
architectures.

A new field seconds_trigger in TOD_Control is introduced to trigger the
_Watchdog_Tickle_seconds() in _TOD_Tickle_ticks(). This avoids the
64-bit divisions completely and only 32-bit additions are used.

  • Property mode set to 100644
File size: 10.4 KB
Line 
1/**
2 *  @file  rtems/score/timestamp64.h
3 *
4 *  This include file contains helpers for manipulating
5 *  64-bit integer timestamps.
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2009.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.com/license/LICENSE.
15 */
16
17#ifndef _RTEMS_SCORE_TIMESTAMP64_H
18#define _RTEMS_SCORE_TIMESTAMP64_H
19
20/**
21 *  @defgroup SuperCore Timestamp64
22 *
23 *  @ingroup Score
24 *
25 *  This handler encapsulates functionality related to manipulating
26 *  the 64 bit integer implementation of SuperCore Timestamps.
27 */
28/**@{*/
29
30#ifdef __cplusplus
31extern "C" {
32#endif
33
34/*
35 *  This .h file is not for general use.  It is an alternative
36 *  implementation of Timestamps and should only be used that way.
37 */
38#ifndef _RTEMS_SCORE_TIMESTAMP_H
39  #error "Should only be included by rtems/score/timestamp.h"
40#endif
41
42/*
43 *  Verify something is defined.
44 */
45#if CPU_TIMESTAMP_USE_INT64 != TRUE && CPU_TIMESTAMP_USE_INT64_INLINE != TRUE
46  #error "SuperCore Timestamp64 implementation included but not defined."
47#endif
48
49/**
50 *   Define the Timestamp control type.
51 */
52typedef int64_t Timestamp64_Control;
53
54static inline void _Timestamp64_implementation_Set(
55  Timestamp64_Control *_time,
56  Timestamp64_Control  _seconds,
57  Timestamp64_Control  _nanoseconds
58)
59{
60  *_time = _seconds * 1000000000L + _nanoseconds;
61}
62
63/**
64 *  @brief Set Timestamp to Seconds Nanosecond
65 *
66 *  This method sets the timestamp to the specified seconds and nanoseconds
67 *  value.
68 *
69 *  @param[in] _time points to the timestamp instance to validate.
70 *  @param[in] _seconds is the seconds portion of the timestamp
71 *  @param[in] _nanoseconds is the nanoseconds portion of the timestamp
72 */
73#if CPU_TIMESTAMP_USE_INT64_INLINE == TRUE
74  #define _Timestamp64_Set( _time, _seconds, _nanoseconds ) \
75    _Timestamp64_implementation_Set( _time, _seconds, _nanoseconds )
76#else
77  void _Timestamp64_Set(
78    Timestamp64_Control *_time,
79    Timestamp64_Control  _seconds,
80    Timestamp64_Control  _nanoseconds
81  );
82#endif
83
84static inline void _Timestamp64_implementation_Set_to_zero(
85  Timestamp64_Control *_time
86)
87{
88  *_time = 0;
89}
90
91/**
92 *  @brief Zero Timestamp
93 *
94 *  This method sets the timestamp to zero.
95 *  value.
96 *
97 *  @param[in] _time points to the timestamp instance to zero.
98 */
99#if CPU_TIMESTAMP_USE_INT64_INLINE == TRUE
100  #define _Timestamp64_Set_to_zero( _time ) \
101    _Timestamp64_implementation_Set_to_zero( _time )
102#else
103  void _Timestamp64_Set_to_zero(
104    Timestamp64_Control *_time
105  );
106#endif
107
108/**
109 *  @brief Is Timestamp Valid
110 *
111 *  This method determines the validity of a timestamp.
112 *
113 *  @param[in] _time points to the timestamp instance to validate.
114 *
115 *  @return This method returns true if @a time is valid and
116 *          false otherwise.
117 */
118#define _Timestamp64_Is_valid( _time ) \
119  (1)
120
121static inline bool _Timestamp64_implementation_Less_than(
122  const Timestamp64_Control *_lhs,
123  const Timestamp64_Control *_rhs
124)
125{
126  return *_lhs < *_rhs;
127}
128
129/**
130 *  @brief Timestamp Less Than Operator
131 *
132 *  This method is the less than operator for timestamps.
133 *
134 *  @param[in] _lhs points to the left hand side timestamp
135 *  @param[in] _rhs points to the right hand side timestamp
136 *
137 *  @return This method returns true if @a _lhs is less than the @a _rhs and
138 *          false otherwise.
139 */
140#if CPU_TIMESTAMP_USE_INT64_INLINE == TRUE
141  #define _Timestamp64_Less_than( _lhs, _rhs ) \
142    _Timestamp64_implementation_Less_than( _lhs, _rhs )
143#else
144  bool _Timestamp64_Less_than(
145    const Timestamp64_Control *_lhs,
146    const Timestamp64_Control *_rhs
147  );
148#endif
149
150static inline bool _Timestamp64_implementation_Equal_to(
151  const Timestamp64_Control *_lhs,
152  const Timestamp64_Control *_rhs
153)
154{
155  return *_lhs == *_rhs;
156}
157
158#define _Timestamp64_Greater_than( _lhs, _rhs ) \
159  _Timestamp64_Less_than( _rhs, _lhs )
160
161/**
162 *  @brief Timestamp equal to Operator
163 *
164 *  This method is the is equal to than operator for timestamps.
165 *
166 *  @param[in] _lhs points to the left hand side timestamp
167 *  @param[in] _rhs points to the right hand side timestamp
168 *
169 *  @return This method returns true if @a _lhs is equal to  @a _rhs and
170 *          false otherwise.
171 */
172#if CPU_TIMESTAMP_USE_INT64_INLINE == TRUE
173  #define _Timestamp64_Equal_to( _lhs, _rhs ) \
174    _Timestamp64_implementation_Equal_to( _lhs, _rhs )
175#else
176  bool _Timestamp64_Equal_to(
177    const Timestamp64_Control *_lhs,
178    const Timestamp64_Control *_rhs
179  );
180#endif
181
182static inline void _Timestamp64_implementation_Add_to(
183  Timestamp64_Control       *_time,
184  const Timestamp64_Control *_add
185)
186{
187  *_time += *_add;
188}
189
190/**
191 *  @brief Add to a Timestamp
192 *
193 *  This routine adds two timestamps.  The second argument is added
194 *  to the first.
195 *
196 *  @param[in] _time points to the base time to be added to
197 *  @param[in] _add points to the timestamp to add to the first argument
198 *
199 *  @return This method returns the number of seconds @a time increased by.
200 */
201#if CPU_TIMESTAMP_USE_INT64_INLINE == TRUE
202  #define _Timestamp64_Add_to( _time, _add ) \
203    _Timestamp64_implementation_Add_to( _time, _add )
204#else
205  void _Timestamp64_Add_to(
206    Timestamp64_Control       *_time,
207    const Timestamp64_Control *_add
208  );
209#endif
210
211/**
212 *  @brief Convert Timestamp to Number of Ticks
213 *
214 *  This routine convert the @a time timestamp to the corresponding number
215 *  of clock ticks.
216 *
217 *  @param[in] _time points to the time to be converted
218 *
219 *  @return This method returns the number of ticks computed.
220 */
221uint32_t _Timestamp64_To_ticks(
222  const Timestamp64_Control *_time
223);
224
225/**
226 *  @brief Convert Ticks to Timestamp
227 *
228 *  This routine converts the @a _ticks value to the corresponding
229 *  timestamp format @a _time.
230 *
231 *  @param[in] _time points to the timestamp format time result
232 *  @param[out] _ticks points to the number of ticks to be filled in
233 */
234void _Timestamp64_From_ticks(
235  uint32_t             _ticks,
236  Timestamp64_Control *_time
237);
238
239static inline void _Timestamp64_implementation_Subtract(
240  const Timestamp64_Control *_start,
241  const Timestamp64_Control *_end,
242  Timestamp64_Control       *_result
243)
244{
245  *_result = *_end - *_start;
246}
247
248/**
249 *  @brief Subtract Two Timestamp
250 *
251 *  This routine subtracts two timestamps.  @a result is set to
252 *  @a end - @a start.
253 *
254 *  @param[in] _start points to the starting time
255 *  @param[in] _end points to the ending time
256 *  @param[out] _result points to the difference between
257 *             starting and ending time.
258 */
259#if CPU_TIMESTAMP_USE_INT64_INLINE == TRUE
260  #define _Timestamp64_Subtract( _start, _end, _result ) \
261    _Timestamp64_implementation_Subtract( _start, _end, _result )
262#else
263  void _Timestamp64_Subtract(
264    const Timestamp64_Control *_start,
265    const Timestamp64_Control *_end,
266    Timestamp64_Control       *_result
267  );
268#endif
269
270static inline void _Timestamp64_implementation_Divide_by_integer(
271  const Timestamp64_Control *_time,
272  uint32_t             _iterations,
273  Timestamp64_Control *_result
274)
275{
276  *_result = *_time / _iterations;
277}
278
279/**
280 *  @brief Divide Timestamp By Integer
281 *
282 *  This routine divides a timestamp by an integer value.  The expected
283 *  use is to assist in benchmark calculations where you typically
284 *  divide a duration by a number of iterations.
285 *
286 *  @param[in] _time points to the total
287 *  @param[in] _iterations is the number of iterations
288 *  @param[out] _result points to the average time.
289 */
290#if CPU_TIMESTAMP_USE_INT64_INLINE == TRUE
291  #define _Timestamp64_Divide_by_integer( _time, _iterations, _result ) \
292    _Timestamp64_implementation_Divide_by_integer( _time, _iterations, _result )
293#else
294  void _Timestamp64_Divide_by_integer(
295    const Timestamp64_Control *_time,
296    uint32_t                   _iterations,
297    Timestamp64_Control       *_result
298  );
299#endif
300
301/**
302 *  @brief Divide Timestamp
303 *
304 *  This routine divides a timestamp by another timestamp.  The
305 *  intended use is for calculating percentages to three decimal points.
306 *
307 *  @param[in] _lhs points to the left hand number
308 *  @param[in] _rhs points to the right hand number
309 *  @param[out] _ival_percentage points to the integer portion of the average
310 *  @param[out] _fval_percentage points to the thousandths of percentage
311 */
312void _Timestamp64_Divide(
313  const Timestamp64_Control *_lhs,
314  const Timestamp64_Control *_rhs,
315  uint32_t                  *_ival_percentage,
316  uint32_t                  *_fval_percentage
317);
318
319static inline uint32_t _Timestamp64_implementation_Get_seconds(
320  const Timestamp64_Control *_time
321)
322{
323  return (uint32_t) (*_time / 1000000000L);
324}
325
326/**
327 *  @brief Get Seconds Portion of Timestamp
328 *
329 *  This method returns the seconds portion of the specified timestamp
330 *
331 *  @param[in] _time points to the timestamp
332 *
333 *  @return The seconds portion of @a _time.
334 */
335#if CPU_TIMESTAMP_USE_INT64_INLINE == TRUE
336  #define _Timestamp64_Get_seconds( _time ) \
337    _Timestamp64_implementation_Get_seconds( _time )
338#else
339  uint32_t _Timestamp64_Get_seconds(
340    const Timestamp64_Control *_time
341  );
342#endif
343
344static inline uint32_t _Timestamp64_implementation_Get_nanoseconds(
345  const Timestamp64_Control *_time
346)
347{
348  return (uint32_t) (*_time % 1000000000L);
349}
350
351/**
352 *  @brief Get Nanoseconds Portion of Timestamp
353 *
354 *  This method returns the nanoseconds portion of the specified timestamp
355 *
356 *  @param[in] _time points to the timestamp
357 *
358 *  @return The nanoseconds portion of @a _time.
359 */
360#if CPU_TIMESTAMP_USE_INT64_INLINE == TRUE
361  #define _Timestamp64_Get_nanoseconds( _time ) \
362    _Timestamp64_implementation_Get_nanoseconds( _time )
363#else
364  uint32_t _Timestamp64_Get_nanoseconds(
365    const Timestamp64_Control *_time
366  );
367#endif
368
369static inline void _Timestamp64_implementation_To_timespec(
370  const Timestamp64_Control *_timestamp,
371  struct timespec           *_timespec
372)
373{
374  _timespec->tv_sec = (time_t) (*_timestamp / 1000000000L);
375  _timespec->tv_nsec = (long) (*_timestamp % 1000000000L);
376}
377
378/**
379 *  @brief Convert Timestamp to struct timespec
380 *
381 *  This method returns the seconds portion of the specified timestamp
382 *
383 *  @param[in] _timestamp points to the timestamp
384 *  @param[out] _timespec points to the timespec
385 */
386#if CPU_TIMESTAMP_USE_INT64_INLINE == TRUE
387  #define _Timestamp64_To_timespec( _timestamp, _timespec  ) \
388    _Timestamp64_implementation_To_timespec( _timestamp, _timespec )
389#else
390  void _Timestamp64_To_timespec(
391    const Timestamp64_Control *_timestamp,
392    struct timespec           *_timespec
393  );
394#endif
395
396#ifdef __cplusplus
397}
398#endif
399
400/**@}*/
401
402#endif
403/* end of include file */
Note: See TracBrowser for help on using the repository browser.