1296221Sjasone#include "jemalloc/internal/jemalloc_internal.h"
2296221Sjasone
3296221Sjasone#define	BILLION	UINT64_C(1000000000)
4296221Sjasone
5296221Sjasonevoid
6296221Sjasonenstime_init(nstime_t *time, uint64_t ns)
7296221Sjasone{
8296221Sjasone
9296221Sjasone	time->ns = ns;
10296221Sjasone}
11296221Sjasone
12296221Sjasonevoid
13296221Sjasonenstime_init2(nstime_t *time, uint64_t sec, uint64_t nsec)
14296221Sjasone{
15296221Sjasone
16296221Sjasone	time->ns = sec * BILLION + nsec;
17296221Sjasone}
18296221Sjasone
19296221Sjasoneuint64_t
20296221Sjasonenstime_ns(const nstime_t *time)
21296221Sjasone{
22296221Sjasone
23296221Sjasone	return (time->ns);
24296221Sjasone}
25296221Sjasone
26296221Sjasoneuint64_t
27296221Sjasonenstime_sec(const nstime_t *time)
28296221Sjasone{
29296221Sjasone
30296221Sjasone	return (time->ns / BILLION);
31296221Sjasone}
32296221Sjasone
33296221Sjasoneuint64_t
34296221Sjasonenstime_nsec(const nstime_t *time)
35296221Sjasone{
36296221Sjasone
37296221Sjasone	return (time->ns % BILLION);
38296221Sjasone}
39296221Sjasone
40296221Sjasonevoid
41296221Sjasonenstime_copy(nstime_t *time, const nstime_t *source)
42296221Sjasone{
43296221Sjasone
44296221Sjasone	*time = *source;
45296221Sjasone}
46296221Sjasone
47296221Sjasoneint
48296221Sjasonenstime_compare(const nstime_t *a, const nstime_t *b)
49296221Sjasone{
50296221Sjasone
51296221Sjasone	return ((a->ns > b->ns) - (a->ns < b->ns));
52296221Sjasone}
53296221Sjasone
54296221Sjasonevoid
55296221Sjasonenstime_add(nstime_t *time, const nstime_t *addend)
56296221Sjasone{
57296221Sjasone
58296221Sjasone	assert(UINT64_MAX - time->ns >= addend->ns);
59296221Sjasone
60296221Sjasone	time->ns += addend->ns;
61296221Sjasone}
62296221Sjasone
63296221Sjasonevoid
64296221Sjasonenstime_subtract(nstime_t *time, const nstime_t *subtrahend)
65296221Sjasone{
66296221Sjasone
67296221Sjasone	assert(nstime_compare(time, subtrahend) >= 0);
68296221Sjasone
69296221Sjasone	time->ns -= subtrahend->ns;
70296221Sjasone}
71296221Sjasone
72296221Sjasonevoid
73296221Sjasonenstime_imultiply(nstime_t *time, uint64_t multiplier)
74296221Sjasone{
75296221Sjasone
76296221Sjasone	assert((((time->ns | multiplier) & (UINT64_MAX << (sizeof(uint64_t) <<
77296221Sjasone	    2))) == 0) || ((time->ns * multiplier) / multiplier == time->ns));
78296221Sjasone
79296221Sjasone	time->ns *= multiplier;
80296221Sjasone}
81296221Sjasone
82296221Sjasonevoid
83296221Sjasonenstime_idivide(nstime_t *time, uint64_t divisor)
84296221Sjasone{
85296221Sjasone
86296221Sjasone	assert(divisor != 0);
87296221Sjasone
88296221Sjasone	time->ns /= divisor;
89296221Sjasone}
90296221Sjasone
91296221Sjasoneuint64_t
92296221Sjasonenstime_divide(const nstime_t *time, const nstime_t *divisor)
93296221Sjasone{
94296221Sjasone
95296221Sjasone	assert(divisor->ns != 0);
96296221Sjasone
97296221Sjasone	return (time->ns / divisor->ns);
98296221Sjasone}
99296221Sjasone
100296221Sjasone#ifdef JEMALLOC_JET
101296221Sjasone#undef nstime_update
102299587Sjasone#define	nstime_update JEMALLOC_N(n_nstime_update)
103296221Sjasone#endif
104296221Sjasonebool
105296221Sjasonenstime_update(nstime_t *time)
106296221Sjasone{
107296221Sjasone	nstime_t old_time;
108296221Sjasone
109296221Sjasone	nstime_copy(&old_time, time);
110296221Sjasone
111296221Sjasone#ifdef _WIN32
112296221Sjasone	{
113296221Sjasone		FILETIME ft;
114296221Sjasone		uint64_t ticks;
115296221Sjasone		GetSystemTimeAsFileTime(&ft);
116296221Sjasone		ticks = (((uint64_t)ft.dwHighDateTime) << 32) |
117296221Sjasone		    ft.dwLowDateTime;
118296221Sjasone		time->ns = ticks * 100;
119296221Sjasone	}
120296221Sjasone#elif JEMALLOC_CLOCK_GETTIME
121296221Sjasone	{
122296221Sjasone		struct timespec ts;
123296221Sjasone
124296221Sjasone		if (sysconf(_SC_MONOTONIC_CLOCK) > 0)
125296221Sjasone			clock_gettime(CLOCK_MONOTONIC, &ts);
126296221Sjasone		else
127296221Sjasone			clock_gettime(CLOCK_REALTIME, &ts);
128296221Sjasone		time->ns = ts.tv_sec * BILLION + ts.tv_nsec;
129296221Sjasone	}
130296221Sjasone#else
131301718Sjasone	{
132301718Sjasone		struct timeval tv;
133301718Sjasone		gettimeofday(&tv, NULL);
134301718Sjasone		time->ns = tv.tv_sec * BILLION + tv.tv_usec * 1000;
135301718Sjasone	}
136296221Sjasone#endif
137296221Sjasone
138296221Sjasone	/* Handle non-monotonic clocks. */
139296221Sjasone	if (unlikely(nstime_compare(&old_time, time) > 0)) {
140296221Sjasone		nstime_copy(time, &old_time);
141296221Sjasone		return (true);
142296221Sjasone	}
143296221Sjasone
144296221Sjasone	return (false);
145296221Sjasone}
146296221Sjasone#ifdef JEMALLOC_JET
147296221Sjasone#undef nstime_update
148296221Sjasone#define	nstime_update JEMALLOC_N(nstime_update)
149299587Sjasonenstime_update_t *nstime_update = JEMALLOC_N(n_nstime_update);
150296221Sjasone#endif
151