1 /**
2 * Copyright (C) Mellanox Technologies Ltd. 2001-2014.  ALL RIGHTS RESERVED.
3 *
4 * See file LICENSE for terms.
5 */
6 
7 #ifndef UCS_TIME_H
8 #define UCS_TIME_H
9 
10 #include <ucs/arch/cpu.h>
11 #include <ucs/time/time_def.h>
12 #include <ucs/sys/math.h>
13 #include <sys/time.h>
14 #include <limits.h>
15 
16 BEGIN_C_DECLS
17 
18 /** @file time.h */
19 
20 /**
21  * Short time type
22  * Used to represent short time intervals, and takes less memory.
23  */
24 typedef uint32_t             ucs_short_time_t;
25 
26 /**
27  * Compare short time values
28  */
29 #define UCS_SHORT_TIME_CMP  UCS_CIRCULAR_COMPARE32
30 
31 
32 #define UCS_TIME_INFINITY  ULLONG_MAX
33 
34 #define UCS_MSEC_PER_SEC   1000ull       /* Milli */
35 #define UCS_USEC_PER_SEC   1000000ul     /* Micro */
36 #define UCS_NSEC_PER_SEC   1000000000ul  /* Nano */
37 
38 
39 double ucs_get_cpu_clocks_per_sec();
40 
41 
42 /**
43  * @return The current time, in UCS time units.
44  */
ucs_get_time()45 static inline ucs_time_t ucs_get_time()
46 {
47     return (ucs_time_t)ucs_arch_read_hres_clock();
48 }
49 
50 /**
51  * @return The current accurate time, in seconds.
52  * @note This function may have higher overhead than @ref ucs_get_time()
53  */
ucs_get_accurate_time()54 static inline double ucs_get_accurate_time()
55 {
56     struct timeval tv;
57     gettimeofday(&tv, NULL);
58     return tv.tv_sec + (tv.tv_usec / (double)UCS_USEC_PER_SEC);
59 }
60 
61 /**
62  * @return The clock value of a single second.
63  */
ucs_time_sec_value()64 static inline double ucs_time_sec_value()
65 {
66     return ucs_get_cpu_clocks_per_sec();
67 }
68 
69 
70 /**
71  * Convert seconds to UCS time units.
72  */
ucs_time_from_sec(double sec)73 static inline ucs_time_t ucs_time_from_sec(double sec)
74 {
75     return (ucs_time_t)(sec * ucs_time_sec_value() + 0.5);
76 }
77 
78 /**
79  * Convert seconds to UCS time units.
80  */
ucs_time_from_msec(double msec)81 static inline ucs_time_t ucs_time_from_msec(double msec)
82 {
83     return ucs_time_from_sec(msec / UCS_MSEC_PER_SEC);
84 }
85 
86 /**
87  * Convert seconds to UCS time units.
88  */
ucs_time_from_usec(double usec)89 static inline ucs_time_t ucs_time_from_usec(double usec)
90 {
91     return ucs_time_from_sec(usec / UCS_USEC_PER_SEC);
92 }
93 
94 /**
95  * Convert UCS time units to seconds.
96  */
ucs_time_to_sec(ucs_time_t t)97 static inline double ucs_time_to_sec(ucs_time_t t)
98 {
99     return t / ucs_time_sec_value();
100 }
101 
102 /**
103  * Convert UCS time units to milliseconds.
104  */
ucs_time_to_msec(ucs_time_t t)105 static inline double ucs_time_to_msec(ucs_time_t t)
106 {
107     return ucs_time_to_sec(t) * UCS_MSEC_PER_SEC;
108 }
109 
110 /**
111  * Convert UCS time units to microseconds.
112  */
ucs_time_to_usec(ucs_time_t t)113 static inline double ucs_time_to_usec(ucs_time_t t)
114 {
115     return ucs_time_to_sec(t) * UCS_USEC_PER_SEC;
116 }
117 
118 /**
119  * Convert UCS time units to nanoseconds.
120  */
ucs_time_to_nsec(ucs_time_t t)121 static inline double ucs_time_to_nsec(ucs_time_t t)
122 {
123     return ucs_time_to_sec(t) * UCS_NSEC_PER_SEC;
124 }
125 
126 /**
127  * Convert UCS time interval (small) to nanoseconds.
128  */
ucs_time_interval_to_nsec(ucs_time_t t)129 static inline double ucs_time_interval_to_nsec(ucs_time_t t)
130 {
131     return ucs_time_to_sec(t * UCS_NSEC_PER_SEC);
132 }
133 
134 /* Convert seconds to POSIX timeval */
ucs_sec_to_timeval(double seconds,struct timeval * tv)135 static inline void ucs_sec_to_timeval(double seconds, struct timeval *tv)
136 {
137     int64_t usec = (int64_t)( (seconds * UCS_USEC_PER_SEC) + 0.5 );
138     tv->tv_sec  = usec / UCS_USEC_PER_SEC;
139     tv->tv_usec = usec % UCS_USEC_PER_SEC;
140 }
141 
142 /* Convert seconds to POSIX timespec */
ucs_sec_to_timespec(double seconds,struct timespec * ts)143 static inline void ucs_sec_to_timespec(double seconds, struct timespec *ts)
144 {
145     int64_t nsec = (int64_t)( (seconds * UCS_NSEC_PER_SEC) + 0.5 );
146     ts->tv_sec  = nsec / UCS_NSEC_PER_SEC;
147     ts->tv_nsec = nsec % UCS_NSEC_PER_SEC;
148 }
149 
150 END_C_DECLS
151 
152 #endif
153