UniRec  2.9.3
ur_time.h
Go to the documentation of this file.
1 
11 /*
12  * Copyright (C) 2013-2015 CESNET
13  *
14  * LICENSE TERMS
15  *
16  * Redistribution and use in source and binary forms, with or without
17  * modification, are permitted provided that the following conditions
18  * are met:
19  * 1. Redistributions of source code must retain the above copyright
20  * notice, this list of conditions and the following disclaimer.
21  * 2. Redistributions in binary form must reproduce the above copyright
22  * notice, this list of conditions and the following disclaimer in
23  * the documentation and/or other materials provided with the
24  * distribution.
25  * 3. Neither the name of the Company nor the names of its contributors
26  * may be used to endorse or promote products derived from this
27  * software without specific prior written permission.
28  *
29  * ALTERNATIVELY, provided that this notice is retained in full, this
30  * product may be distributed under the terms of the GNU General Public
31  * License (GPL) version 2 or later, in which case the provisions
32  * of the GPL apply INSTEAD OF those given above.
33  *
34  * This software is provided ``as is'', and any express or implied
35  * warranties, including, but not limited to, the implied warranties of
36  * merchantability and fitness for a particular purpose are disclaimed.
37  * In no event shall the company or contributors be liable for any
38  * direct, indirect, incidental, special, exemplary, or consequential
39  * damages (including, but not limited to, procurement of substitute
40  * goods or services; loss of use, data, or profits; or business
41  * interruption) however caused and on any theory of liability, whether
42  * in contract, strict liability, or tort (including negligence or
43  * otherwise) arising in any way out of the use of this software, even
44  * if advised of the possibility of such damage.
45  *
46  */
47 #ifndef _UR_TIME_H
48 #define _UR_TIME_H
49 
50 #include <stdint.h>
51 
61 typedef uint64_t ur_time_t;
62 
67 #define UR_TIME_NSEC_TO_FRAC 0x44B82FA0AULL
68 //#define UR_TIME_USEC_TO_FRAC 0x10C6F7A0B5EEULL
69 //#define UR_TIME_MSEC_TO_FRAC 0x4189374BC6A7F0ULL
70 
71 /*
72 Note: We could use spearate constants for direct conversion from ms, us
73 and ns, but each such constant would have a different rounding error.
74 It would result in incorrect results when a value would be encoded from
75 one precision and decoded in another one (e.g. store as ms -> read as us
76 wouldn't result in a number like "x.xxx000").
77 The only consistent way is to always convert to fixed-point using the
78 highest precision (ns) and do additional conversion to/from ms/us by
79 multiplying/dividing it by 1000 or 1000000, i.e. in decadic form.
80 
81 The current implementation satisfies these rules:
82 (everything is related to the fractional part only, the integer part is easy)
83 - Converting the time to unirec and back using the same precision always results
84  in exactly the same number. Example:
85  123456us -> ur_time -> 123456us
86 - Setting the time in lower precision and reading it in higer precision
87  results in a number ending with zeros. Example:
88  123ms -> ur_time -> 123000000ns
89 - Seting the time in higher precision and reading it in lower precision
90  results in a floored value (i.e. rounded down). Example:
91  199999us -> ur_time -> 199ms
92 */
93 
94 
100 #define ur_time_from_sec_nsec(sec, nsec) \
101  (ur_time_t) (((uint64_t) (sec) << 32) | (((uint64_t) (nsec) * UR_TIME_NSEC_TO_FRAC) >> 32))
102 
108 #define ur_time_from_sec_usec(sec, usec) \
109  (ur_time_t) (((uint64_t) (sec) << 32) | (((uint64_t) (usec) * 1000 * UR_TIME_NSEC_TO_FRAC) >> 32))
110 
116 #define ur_time_from_sec_msec(sec, msec) \
117  (ur_time_t) (((uint64_t) (sec) << 32) | (((uint64_t) (msec) * 1000000 * UR_TIME_NSEC_TO_FRAC) >> 32))
118 
119 
124 #define ur_time_get_sec(time) \
125  (uint32_t) ((uint64_t) (time) >> 32)
126 
127 
132 #define ur_time_get_nsec(time) \
133  (uint32_t) ((((uint64_t) (time) & 0xffffffff) * 1000000000ULL + 0xffffffff) >> 32)
134 
139 #define ur_time_get_usec(time) \
140  (uint32_t) (ur_time_get_nsec(time) / 1000)
141 
146 #define ur_time_get_msec(time) \
147  (uint32_t) (ur_time_get_nsec(time) / 1000000)
148 
149 
157 static inline uint64_t ur_timediff(ur_time_t a, ur_time_t b)
158 {
159  ur_time_t c = (a > b) ? a - b : b - a;
160  return (uint64_t) ur_time_get_sec(c) * 1000 + ur_time_get_msec(c);
161 }
162 
170 static inline uint64_t ur_timediff_us(ur_time_t a, ur_time_t b)
171 {
172  ur_time_t c = (a > b) ? a - b : b - a;
173  return (uint64_t) ur_time_get_sec(c) * 1000000 + ur_time_get_usec(c);
174 }
175 
183 static inline uint64_t ur_timediff_ns(ur_time_t a, ur_time_t b)
184 {
185  ur_time_t c = (a > b) ? a - b : b - a;
186  return (uint64_t) ur_time_get_sec(c) * 1000000000 + ur_time_get_nsec(c);
187 }
188 
200 uint8_t ur_time_from_string(ur_time_t *ur, const char *str);
201 // hint: implementation is in unirec.c
202 
207 #endif
uint8_t ur_time_from_string(ur_time_t *ur, const char *str)
Definition: unirec.c:1606
static uint64_t ur_timediff_us(ur_time_t a, ur_time_t b)
Definition: ur_time.h:170
uint64_t ur_time_t
Type of timestamps used in UniRec Timestamps in UniRec are stored as number of seconds from Unix epoc...
Definition: ur_time.h:61
#define ur_time_get_sec(time)
Get number of seconds from ur_time_t.
Definition: ur_time.h:124
#define ur_time_get_msec(time)
Get number of milliseconds from ur_time_t.
Definition: ur_time.h:146
static uint64_t ur_timediff(ur_time_t a, ur_time_t b)
Definition: ur_time.h:157
#define ur_time_get_nsec(time)
Get number of nanoseconds from ur_time_t.
Definition: ur_time.h:132
#define ur_time_get_usec(time)
Get number of microeconds from ur_time_t.
Definition: ur_time.h:139
static uint64_t ur_timediff_ns(ur_time_t a, ur_time_t b)
Definition: ur_time.h:183