Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5270 serge 1
#ifndef _LINUX_TIME64_H
2
#define _LINUX_TIME64_H
3
 
4
#include 
5
 
6
typedef __s64 time64_t;
7
 
8
/*
9
 * This wants to go into uapi/linux/time.h once we agreed about the
10
 * userspace interfaces.
11
 */
12
#if __BITS_PER_LONG == 64
13
# define timespec64 timespec
14
#else
15
struct timespec64 {
16
	time64_t	tv_sec;			/* seconds */
17
	long		tv_nsec;		/* nanoseconds */
18
};
19
#endif
20
 
21
/* Parameters used to convert the timespec values: */
22
#define MSEC_PER_SEC	1000L
23
#define USEC_PER_MSEC	1000L
24
#define NSEC_PER_USEC	1000L
25
#define NSEC_PER_MSEC	1000000L
26
#define USEC_PER_SEC	1000000L
27
#define NSEC_PER_SEC	1000000000L
28
#define FSEC_PER_SEC	1000000000000000LL
29
 
30
/* Located here for timespec[64]_valid_strict */
31
#define KTIME_MAX			((s64)~((u64)1 << 63))
32
#define KTIME_SEC_MAX			(KTIME_MAX / NSEC_PER_SEC)
33
 
34
#if __BITS_PER_LONG == 64
35
 
36
static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64)
37
{
38
	return ts64;
39
}
40
 
41
static inline struct timespec64 timespec_to_timespec64(const struct timespec ts)
42
{
43
	return ts;
44
}
45
 
46
# define timespec64_equal		timespec_equal
47
# define timespec64_compare		timespec_compare
48
# define set_normalized_timespec64	set_normalized_timespec
49
# define timespec64_add_safe		timespec_add_safe
50
# define timespec64_add			timespec_add
51
# define timespec64_sub			timespec_sub
52
# define timespec64_valid		timespec_valid
53
# define timespec64_valid_strict	timespec_valid_strict
54
# define timespec64_to_ns		timespec_to_ns
55
# define ns_to_timespec64		ns_to_timespec
56
# define timespec64_add_ns		timespec_add_ns
57
 
58
#else
59
 
60
static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64)
61
{
62
	struct timespec ret;
63
 
64
	ret.tv_sec = (time_t)ts64.tv_sec;
65
	ret.tv_nsec = ts64.tv_nsec;
66
	return ret;
67
}
68
 
69
static inline struct timespec64 timespec_to_timespec64(const struct timespec ts)
70
{
71
	struct timespec64 ret;
72
 
73
	ret.tv_sec = ts.tv_sec;
74
	ret.tv_nsec = ts.tv_nsec;
75
	return ret;
76
}
77
 
78
static inline int timespec64_equal(const struct timespec64 *a,
79
				   const struct timespec64 *b)
80
{
81
	return (a->tv_sec == b->tv_sec) && (a->tv_nsec == b->tv_nsec);
82
}
83
 
84
/*
85
 * lhs < rhs:  return <0
86
 * lhs == rhs: return 0
87
 * lhs > rhs:  return >0
88
 */
89
static inline int timespec64_compare(const struct timespec64 *lhs, const struct timespec64 *rhs)
90
{
91
	if (lhs->tv_sec < rhs->tv_sec)
92
		return -1;
93
	if (lhs->tv_sec > rhs->tv_sec)
94
		return 1;
95
	return lhs->tv_nsec - rhs->tv_nsec;
96
}
97
 
98
extern void set_normalized_timespec64(struct timespec64 *ts, time64_t sec, s64 nsec);
99
 
100
/*
101
 * timespec64_add_safe assumes both values are positive and checks for
102
 * overflow. It will return TIME_T_MAX if the returned value would be
103
 * smaller then either of the arguments.
104
 */
105
extern struct timespec64 timespec64_add_safe(const struct timespec64 lhs,
106
					 const struct timespec64 rhs);
107
 
108
 
109
static inline struct timespec64 timespec64_add(struct timespec64 lhs,
110
						struct timespec64 rhs)
111
{
112
	struct timespec64 ts_delta;
113
	set_normalized_timespec64(&ts_delta, lhs.tv_sec + rhs.tv_sec,
114
				lhs.tv_nsec + rhs.tv_nsec);
115
	return ts_delta;
116
}
117
 
118
/*
119
 * sub = lhs - rhs, in normalized form
120
 */
121
static inline struct timespec64 timespec64_sub(struct timespec64 lhs,
122
						struct timespec64 rhs)
123
{
124
	struct timespec64 ts_delta;
125
	set_normalized_timespec64(&ts_delta, lhs.tv_sec - rhs.tv_sec,
126
				lhs.tv_nsec - rhs.tv_nsec);
127
	return ts_delta;
128
}
129
 
130
/*
131
 * Returns true if the timespec64 is norm, false if denorm:
132
 */
133
static inline bool timespec64_valid(const struct timespec64 *ts)
134
{
135
	/* Dates before 1970 are bogus */
136
	if (ts->tv_sec < 0)
137
		return false;
138
	/* Can't have more nanoseconds then a second */
139
	if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC)
140
		return false;
141
	return true;
142
}
143
 
144
static inline bool timespec64_valid_strict(const struct timespec64 *ts)
145
{
146
	if (!timespec64_valid(ts))
147
		return false;
148
	/* Disallow values that could overflow ktime_t */
149
	if ((unsigned long long)ts->tv_sec >= KTIME_SEC_MAX)
150
		return false;
151
	return true;
152
}
153
 
154
/**
155
 * timespec64_to_ns - Convert timespec64 to nanoseconds
156
 * @ts:		pointer to the timespec64 variable to be converted
157
 *
158
 * Returns the scalar nanosecond representation of the timespec64
159
 * parameter.
160
 */
161
static inline s64 timespec64_to_ns(const struct timespec64 *ts)
162
{
163
	return ((s64) ts->tv_sec * NSEC_PER_SEC) + ts->tv_nsec;
164
}
165
 
166
/**
167
 * ns_to_timespec64 - Convert nanoseconds to timespec64
168
 * @nsec:	the nanoseconds value to be converted
169
 *
170
 * Returns the timespec64 representation of the nsec parameter.
171
 */
172
extern struct timespec64 ns_to_timespec64(const s64 nsec);
173
 
174
/**
175
 * timespec64_add_ns - Adds nanoseconds to a timespec64
176
 * @a:		pointer to timespec64 to be incremented
177
 * @ns:		unsigned nanoseconds value to be added
178
 *
179
 * This must always be inlined because its used from the x86-64 vdso,
180
 * which cannot call other kernel functions.
181
 */
182
static __always_inline void timespec64_add_ns(struct timespec64 *a, u64 ns)
183
{
184
	a->tv_sec += __iter_div_u64_rem(a->tv_nsec + ns, NSEC_PER_SEC, &ns);
185
	a->tv_nsec = ns;
186
}
187
 
188
#endif
189
 
190
#endif /* _LINUX_TIME64_H */