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 _WIN32 101 # define NSTIME_MONOTONIC true 102 static void 103 nstime_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 } 113 #elif JEMALLOC_HAVE_CLOCK_MONOTONIC_COARSE 114 # define NSTIME_MONOTONIC true 115 static void 116 nstime_get(nstime_t *time) 117 { 118 struct timespec ts; 119 120 clock_gettime(CLOCK_MONOTONIC_COARSE, &ts); 121 nstime_init2(time, ts.tv_sec, ts.tv_nsec); 122 } 123 #elif JEMALLOC_HAVE_CLOCK_MONOTONIC 124 # define NSTIME_MONOTONIC true 125 static void 126 nstime_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 134 # define NSTIME_MONOTONIC true 135 static void 136 nstime_get(nstime_t *time) 137 { 138 139 nstime_init(time, mach_absolute_time()); 140 } 141 #else 142 # define NSTIME_MONOTONIC false 143 static void 144 nstime_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 153 #ifdef JEMALLOC_JET 154 #undef nstime_monotonic 155 #define nstime_monotonic JEMALLOC_N(n_nstime_monotonic) 156 #endif 157 bool 158 nstime_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) 167 nstime_monotonic_t *nstime_monotonic = JEMALLOC_N(n_nstime_monotonic); 168 #endif 169 170 #ifdef JEMALLOC_JET 171 #undef nstime_update 172 #define nstime_update JEMALLOC_N(n_nstime_update) 173 #endif 174 bool 175 nstime_update(nstime_t *time) 176 { 177 nstime_t old_time; 178 179 nstime_copy(&old_time, time); 180 nstime_get(time); 181 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) 193 nstime_update_t *nstime_update = JEMALLOC_N(n_nstime_update); 194 #endif 195