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
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
100#ifdef JEMALLOC_JET
101#undef nstime_update
102#define	nstime_update JEMALLOC_N(n_nstime_update)
103#endif
104bool
105nstime_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)
149nstime_update_t *nstime_update = JEMALLOC_N(n_nstime_update);
150#endif
151