1 | #include "jemalloc/internal/jemalloc_internal.h" |
2 | |
3 | #define BILLION UINT64_C(1000000000) |
4 | |
5 | void |
6 | nstime_init(nstime_t *time, uint64_t ns) |
7 | { |
8 | |
9 | time->ns = ns; |
10 | } |
11 | |
12 | void |
13 | nstime_init2(nstime_t *time, uint64_t sec, uint64_t nsec) |
14 | { |
15 | |
16 | time->ns = sec * BILLION + nsec; |
17 | } |
18 | |
19 | uint64_t |
20 | nstime_ns(const nstime_t *time) |
21 | { |
22 | |
23 | return (time->ns); |
24 | } |
25 | |
26 | uint64_t |
27 | nstime_sec(const nstime_t *time) |
28 | { |
29 | |
30 | return (time->ns / BILLION); |
31 | } |
32 | |
33 | uint64_t |
34 | nstime_nsec(const nstime_t *time) |
35 | { |
36 | |
37 | return (time->ns % BILLION); |
38 | } |
39 | |
40 | void |
41 | nstime_copy(nstime_t *time, const nstime_t *source) |
42 | { |
43 | |
44 | *time = *source; |
45 | } |
46 | |
47 | int |
48 | nstime_compare(const nstime_t *a, const nstime_t *b) |
49 | { |
50 | |
51 | return ((a->ns > b->ns) - (a->ns < b->ns)); |
52 | } |
53 | |
54 | void |
55 | nstime_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 | |
63 | void |
64 | nstime_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 | |
72 | void |
73 | nstime_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 | |
82 | void |
83 | nstime_idivide(nstime_t *time, uint64_t divisor) |
84 | { |
85 | |
86 | assert(divisor != 0); |
87 | |
88 | time->ns /= divisor; |
89 | } |
90 | |
91 | uint64_t |
92 | nstime_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 | |
100 | #ifdef JEMALLOC_JET |
101 | #undef nstime_update |
102 | #define nstime_update JEMALLOC_N(n_nstime_update) |
103 | #endif |
104 | bool |
105 | nstime_update(nstime_t *time) |
106 | { |
107 | nstime_t old_time; |
108 | |
109 | nstime_copy(&old_time, time); |
110 | |
111 | #ifdef _WIN32 |
112 | { |
113 | FILETIME ft; |
114 | uint64_t ticks; |
115 | GetSystemTimeAsFileTime(&ft); |
116 | ticks = (((uint64_t)ft.dwHighDateTime) << 32) | |
117 | ft.dwLowDateTime; |
118 | time->ns = ticks * 100; |
119 | } |
120 | #elif JEMALLOC_CLOCK_GETTIME |
121 | { |
122 | struct timespec ts; |
123 | |
124 | if (sysconf(_SC_MONOTONIC_CLOCK) > 0) |
125 | clock_gettime(CLOCK_MONOTONIC, &ts); |
126 | else |
127 | clock_gettime(CLOCK_REALTIME, &ts); |
128 | time->ns = ts.tv_sec * BILLION + ts.tv_nsec; |
129 | } |
130 | #else |
131 | { |
132 | struct timeval tv; |
133 | gettimeofday(&tv, NULL); |
134 | time->ns = tv.tv_sec * BILLION + tv.tv_usec * 1000; |
135 | } |
136 | #endif |
137 | |
138 | /* Handle non-monotonic clocks. */ |
139 | if (unlikely(nstime_compare(&old_time, time) > 0)) { |
140 | nstime_copy(time, &old_time); |
141 | return (true); |
142 | } |
143 | |
144 | return (false); |
145 | } |
146 | #ifdef JEMALLOC_JET |
147 | #undef nstime_update |
148 | #define nstime_update JEMALLOC_N(nstime_update) |
149 | nstime_update_t *nstime_update = JEMALLOC_N(n_nstime_update); |
150 | #endif |
151 | |