blob: 0948e29faffa5eeb8abdf0c9038aac8f4a77f940 [file] [log] [blame]
Jason Evans9bad0792016-02-21 11:25:02 -08001#include "jemalloc/internal/jemalloc_internal.h"
2
3#define BILLION UINT64_C(1000000000)
4
5void
6nstime_init(nstime_t *time, uint64_t ns)
7{
8
9 time->ns = ns;
10}
11
12void
13nstime_init2(nstime_t *time, uint64_t sec, uint64_t nsec)
14{
15
16 time->ns = sec * BILLION + nsec;
17}
18
19uint64_t
20nstime_ns(const nstime_t *time)
21{
22
23 return (time->ns);
24}
25
26uint64_t
27nstime_sec(const nstime_t *time)
28{
29
30 return (time->ns / BILLION);
31}
32
33uint64_t
34nstime_nsec(const nstime_t *time)
35{
36
37 return (time->ns % BILLION);
38}
39
40void
41nstime_copy(nstime_t *time, const nstime_t *source)
42{
43
44 *time = *source;
45}
46
47int
48nstime_compare(const nstime_t *a, const nstime_t *b)
49{
50
51 return ((a->ns > b->ns) - (a->ns < b->ns));
52}
53
54void
55nstime_add(nstime_t *time, const nstime_t *addend)
56{
57
58 assert(UINT64_MAX - time->ns >= addend->ns);
59
60 time->ns += addend->ns;
61}
62
63void
64nstime_subtract(nstime_t *time, const nstime_t *subtrahend)
65{
66
67 assert(nstime_compare(time, subtrahend) >= 0);
68
69 time->ns -= subtrahend->ns;
70}
71
72void
73nstime_imultiply(nstime_t *time, uint64_t multiplier)
74{
75
76 assert((((time->ns | multiplier) & (UINT64_MAX << (sizeof(uint64_t) <<
77 2))) == 0) || ((time->ns * multiplier) / multiplier == time->ns));
78
79 time->ns *= multiplier;
80}
81
82void
83nstime_idivide(nstime_t *time, uint64_t divisor)
84{
85
86 assert(divisor != 0);
87
88 time->ns /= divisor;
89}
90
91uint64_t
92nstime_divide(const nstime_t *time, const nstime_t *divisor)
93{
94
95 assert(divisor->ns != 0);
96
97 return (time->ns / divisor->ns);
98}
99
Jason Evansb732c392016-10-07 08:47:16 -0700100#ifdef _WIN32
Jason Evans45a5bf62016-10-10 22:15:10 -0700101# define NSTIME_MONOTONIC true
Jason Evansb732c392016-10-07 08:47:16 -0700102static void
103nstime_get(nstime_t *time)
104{
105 FILETIME ft;
106 uint64_t ticks_100ns;
107
108 GetSystemTimeAsFileTime(&ft);
109 ticks_100ns = (((uint64_t)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
110
111 nstime_init(time, ticks_100ns * 100);
112}
Jason Evans1d57c032016-10-29 22:55:08 -0700113#elif JEMALLOC_HAVE_CLOCK_MONOTONIC_COARSE
Jason Evans45a5bf62016-10-10 22:15:10 -0700114# define NSTIME_MONOTONIC true
Jason Evansb732c392016-10-07 08:47:16 -0700115static void
116nstime_get(nstime_t *time)
117{
118 struct timespec ts;
119
Jason Evans1d57c032016-10-29 22:55:08 -0700120 clock_gettime(CLOCK_MONOTONIC_COARSE, &ts);
Jason Evansb732c392016-10-07 08:47:16 -0700121 nstime_init2(time, ts.tv_sec, ts.tv_nsec);
122}
123#elif JEMALLOC_HAVE_CLOCK_MONOTONIC
Jason Evans45a5bf62016-10-10 22:15:10 -0700124# define NSTIME_MONOTONIC true
Jason Evansb732c392016-10-07 08:47:16 -0700125static void
126nstime_get(nstime_t *time)
127{
128 struct timespec ts;
129
130 clock_gettime(CLOCK_MONOTONIC, &ts);
131 nstime_init2(time, ts.tv_sec, ts.tv_nsec);
132}
133#elif JEMALLOC_HAVE_MACH_ABSOLUTE_TIME
Jason Evans45a5bf62016-10-10 22:15:10 -0700134# define NSTIME_MONOTONIC true
Jason Evansb732c392016-10-07 08:47:16 -0700135static void
136nstime_get(nstime_t *time)
137{
138
139 nstime_init(time, mach_absolute_time());
140}
141#else
Jason Evans45a5bf62016-10-10 22:15:10 -0700142# define NSTIME_MONOTONIC false
Jason Evansb732c392016-10-07 08:47:16 -0700143static void
144nstime_get(nstime_t *time)
145{
146 struct timeval tv;
147
148 gettimeofday(&tv, NULL);
149 nstime_init2(time, tv.tv_sec, tv.tv_usec * 1000);
150}
151#endif
152
Jason Evans9bad0792016-02-21 11:25:02 -0800153#ifdef JEMALLOC_JET
Jason Evans45a5bf62016-10-10 22:15:10 -0700154#undef nstime_monotonic
155#define nstime_monotonic JEMALLOC_N(n_nstime_monotonic)
156#endif
157bool
158nstime_monotonic(void)
159{
160
161 return (NSTIME_MONOTONIC);
162#undef NSTIME_MONOTONIC
163}
164#ifdef JEMALLOC_JET
165#undef nstime_monotonic
166#define nstime_monotonic JEMALLOC_N(nstime_monotonic)
167nstime_monotonic_t *nstime_monotonic = JEMALLOC_N(n_nstime_monotonic);
168#endif
169
170#ifdef JEMALLOC_JET
Jason Evans9bad0792016-02-21 11:25:02 -0800171#undef nstime_update
Jason Evansab0cfe02016-04-18 15:11:20 -0700172#define nstime_update JEMALLOC_N(n_nstime_update)
Jason Evans9bad0792016-02-21 11:25:02 -0800173#endif
174bool
175nstime_update(nstime_t *time)
176{
177 nstime_t old_time;
178
179 nstime_copy(&old_time, time);
Jason Evansb732c392016-10-07 08:47:16 -0700180 nstime_get(time);
Jason Evans9bad0792016-02-21 11:25:02 -0800181
182 /* Handle non-monotonic clocks. */
183 if (unlikely(nstime_compare(&old_time, time) > 0)) {
184 nstime_copy(time, &old_time);
185 return (true);
186 }
187
188 return (false);
189}
190#ifdef JEMALLOC_JET
191#undef nstime_update
192#define nstime_update JEMALLOC_N(nstime_update)
Jason Evansab0cfe02016-04-18 15:11:20 -0700193nstime_update_t *nstime_update = JEMALLOC_N(n_nstime_update);
Jason Evans9bad0792016-02-21 11:25:02 -0800194#endif