1#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 time->ns = ns; 9} 10 11void 12nstime_init2(nstime_t *time, uint64_t sec, uint64_t nsec) 13{ 14 time->ns = sec * BILLION + nsec; 15} 16 17uint64_t 18nstime_ns(const nstime_t *time) 19{ 20 return (time->ns); 21} 22 23uint64_t 24nstime_sec(const nstime_t *time) 25{ 26 return (time->ns / BILLION); 27} 28 29uint64_t 30nstime_nsec(const nstime_t *time) 31{ 32 return (time->ns % BILLION); 33} 34 35void 36nstime_copy(nstime_t *time, const nstime_t *source) 37{ 38 *time = *source; 39} 40 41int 42nstime_compare(const nstime_t *a, const nstime_t *b) 43{ 44 return ((a->ns > b->ns) - (a->ns < b->ns)); 45} 46 47void 48nstime_add(nstime_t *time, const nstime_t *addend) 49{ 50 assert(UINT64_MAX - time->ns >= addend->ns); 51 52 time->ns += addend->ns; 53} 54 55void 56nstime_subtract(nstime_t *time, const nstime_t *subtrahend) 57{ 58 assert(nstime_compare(time, subtrahend) >= 0); 59 60 time->ns -= subtrahend->ns; 61} 62 63void 64nstime_imultiply(nstime_t *time, uint64_t multiplier) 65{ 66 assert((((time->ns | multiplier) & (UINT64_MAX << (sizeof(uint64_t) << 67 2))) == 0) || ((time->ns * multiplier) / multiplier == time->ns)); 68 69 time->ns *= multiplier; 70} 71 72void 73nstime_idivide(nstime_t *time, uint64_t divisor) 74{ 75 assert(divisor != 0); 76 77 time->ns /= divisor; 78} 79 80uint64_t 81nstime_divide(const nstime_t *time, const nstime_t *divisor) 82{ 83 assert(divisor->ns != 0); 84 85 return (time->ns / divisor->ns); 86} 87 88#ifdef _WIN32 89# define NSTIME_MONOTONIC true 90static void 91nstime_get(nstime_t *time) 92{ 93 FILETIME ft; 94 uint64_t ticks_100ns; 95 96 GetSystemTimeAsFileTime(&ft); 97 ticks_100ns = (((uint64_t)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; 98 99 nstime_init(time, ticks_100ns * 100); 100} 101#elif JEMALLOC_HAVE_CLOCK_MONOTONIC_COARSE 102# define NSTIME_MONOTONIC true 103static void 104nstime_get(nstime_t *time) 105{ 106 struct timespec ts; 107 108 clock_gettime(CLOCK_MONOTONIC_COARSE, &ts); 109 nstime_init2(time, ts.tv_sec, ts.tv_nsec); 110} 111#elif JEMALLOC_HAVE_CLOCK_MONOTONIC 112# define NSTIME_MONOTONIC true 113static void 114nstime_get(nstime_t *time) 115{ 116 struct timespec ts; 117 118 clock_gettime(CLOCK_MONOTONIC, &ts); 119 nstime_init2(time, ts.tv_sec, ts.tv_nsec); 120} 121#elif JEMALLOC_HAVE_MACH_ABSOLUTE_TIME 122# define NSTIME_MONOTONIC true 123static void 124nstime_get(nstime_t *time) 125{ 126 nstime_init(time, mach_absolute_time()); 127} 128#else 129# define NSTIME_MONOTONIC false 130static void 131nstime_get(nstime_t *time) 132{ 133 struct timeval tv; 134 135 gettimeofday(&tv, NULL); 136 nstime_init2(time, tv.tv_sec, tv.tv_usec * 1000); 137} 138#endif 139 140#ifdef JEMALLOC_JET 141#undef nstime_monotonic 142#define nstime_monotonic JEMALLOC_N(n_nstime_monotonic) 143#endif 144bool 145nstime_monotonic(void) 146{ 147 return (NSTIME_MONOTONIC); 148#undef NSTIME_MONOTONIC 149} 150#ifdef JEMALLOC_JET 151#undef nstime_monotonic 152#define nstime_monotonic JEMALLOC_N(nstime_monotonic) 153nstime_monotonic_t *nstime_monotonic = JEMALLOC_N(n_nstime_monotonic); 154#endif 155 156#ifdef JEMALLOC_JET 157#undef nstime_update 158#define nstime_update JEMALLOC_N(n_nstime_update) 159#endif 160bool 161nstime_update(nstime_t *time) 162{ 163 nstime_t old_time; 164 165 nstime_copy(&old_time, time); 166 nstime_get(time); 167 168 /* Handle non-monotonic clocks. */ 169 if (unlikely(nstime_compare(&old_time, time) > 0)) { 170 nstime_copy(time, &old_time); 171 return (true); 172 } 173 174 return (false); 175} 176#ifdef JEMALLOC_JET 177#undef nstime_update 178#define nstime_update JEMALLOC_N(nstime_update) 179nstime_update_t *nstime_update = JEMALLOC_N(n_nstime_update); 180#endif 181