Subversion Repositories Kolibri OS

Rev

Rev 4921 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/* time.h -- An implementation of the standard Unix  file.
2
   Written by Geoffrey Noer 
3
   Public domain; no rights reserved. */
4
 
6099 serge 5
/*-
6
 * Copyright (c) 1982, 1986, 1993
7
 *	The Regents of the University of California.  All rights reserved.
8
 *
9
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions
11
 * are met:
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 * 2. Redistributions in binary form must reproduce the above copyright
15
 *    notice, this list of conditions and the following disclaimer in the
16
 *    documentation and/or other materials provided with the distribution.
17
 * 4. Neither the name of the University nor the names of its contributors
18
 *    may be used to endorse or promote products derived from this software
19
 *    without specific prior written permission.
20
 *
21
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31
 * SUCH DAMAGE.
32
 *
33
 *	@(#)time.h	8.5 (Berkeley) 5/4/95
34
 * $FreeBSD$
35
 */
36
 
4349 Serge 37
#ifndef _SYS_TIME_H_
6099 serge 38
#define	_SYS_TIME_H_
4349 Serge 39
 
40
#include <_ansi.h>
6099 serge 41
#include 
42
#include 
4349 Serge 43
#include 
6099 serge 44
#include 
4349 Serge 45
 
6099 serge 46
#if __BSD_VISIBLE
47
#include 
4349 Serge 48
#endif
49
 
6099 serge 50
struct timezone {
51
	int	tz_minuteswest;	/* minutes west of Greenwich */
52
	int	tz_dsttime;	/* type of dst correction */
4349 Serge 53
};
6099 serge 54
#define	DST_NONE	0	/* not on dst */
55
#define	DST_USA		1	/* USA style dst */
56
#define	DST_AUST	2	/* Australian style dst */
57
#define	DST_WET		3	/* Western European dst */
58
#define	DST_MET		4	/* Middle European dst */
59
#define	DST_EET		5	/* Eastern European dst */
60
#define	DST_CAN		6	/* Canada */
4349 Serge 61
 
6099 serge 62
#if __BSD_VISIBLE
63
struct bintime {
64
	time_t	sec;
65
	uint64_t frac;
66
};
4349 Serge 67
 
6099 serge 68
static __inline void
69
bintime_addx(struct bintime *_bt, uint64_t _x)
70
{
71
	uint64_t _u;
4349 Serge 72
 
6099 serge 73
	_u = _bt->frac;
74
	_bt->frac += _x;
75
	if (_u > _bt->frac)
76
		_bt->sec++;
77
}
4921 Serge 78
 
6099 serge 79
static __inline void
80
bintime_add(struct bintime *_bt, const struct bintime *_bt2)
81
{
82
	uint64_t _u;
4921 Serge 83
 
6099 serge 84
	_u = _bt->frac;
85
	_bt->frac += _bt2->frac;
86
	if (_u > _bt->frac)
87
		_bt->sec++;
88
	_bt->sec += _bt2->sec;
89
}
4921 Serge 90
 
6099 serge 91
static __inline void
92
bintime_sub(struct bintime *_bt, const struct bintime *_bt2)
93
{
94
	uint64_t _u;
95
 
96
	_u = _bt->frac;
97
	_bt->frac -= _bt2->frac;
98
	if (_u < _bt->frac)
99
		_bt->sec--;
100
	_bt->sec -= _bt2->sec;
101
}
102
 
103
static __inline void
104
bintime_mul(struct bintime *_bt, u_int _x)
105
{
106
	uint64_t _p1, _p2;
107
 
108
	_p1 = (_bt->frac & 0xffffffffull) * _x;
109
	_p2 = (_bt->frac >> 32) * _x + (_p1 >> 32);
110
	_bt->sec *= _x;
111
	_bt->sec += (_p2 >> 32);
112
	_bt->frac = (_p2 << 32) | (_p1 & 0xffffffffull);
113
}
114
 
115
static __inline void
116
bintime_shift(struct bintime *_bt, int _exp)
117
{
118
 
119
	if (_exp > 0) {
120
		_bt->sec <<= _exp;
121
		_bt->sec |= _bt->frac >> (64 - _exp);
122
		_bt->frac <<= _exp;
123
	} else if (_exp < 0) {
124
		_bt->frac >>= -_exp;
125
		_bt->frac |= (uint64_t)_bt->sec << (64 + _exp);
126
		_bt->sec >>= -_exp;
127
	}
128
}
129
 
130
#define	bintime_clear(a)	((a)->sec = (a)->frac = 0)
131
#define	bintime_isset(a)	((a)->sec || (a)->frac)
132
#define	bintime_cmp(a, b, cmp)						\
133
	(((a)->sec == (b)->sec) ?					\
134
	    ((a)->frac cmp (b)->frac) :					\
135
	    ((a)->sec cmp (b)->sec))
136
 
137
#define	SBT_1S	((sbintime_t)1 << 32)
138
#define	SBT_1M	(SBT_1S * 60)
139
#define	SBT_1MS	(SBT_1S / 1000)
140
#define	SBT_1US	(SBT_1S / 1000000)
141
#define	SBT_1NS	(SBT_1S / 1000000000)
142
#define	SBT_MAX	0x7fffffffffffffffLL
143
 
144
static __inline int
145
sbintime_getsec(sbintime_t _sbt)
146
{
147
 
148
	return (_sbt >> 32);
149
}
150
 
151
static __inline sbintime_t
152
bttosbt(const struct bintime _bt)
153
{
154
 
155
	return (((sbintime_t)_bt.sec << 32) + (_bt.frac >> 32));
156
}
157
 
158
static __inline struct bintime
159
sbttobt(sbintime_t _sbt)
160
{
161
	struct bintime _bt;
162
 
163
	_bt.sec = _sbt >> 32;
164
	_bt.frac = _sbt << 32;
165
	return (_bt);
166
}
167
 
168
/*-
169
 * Background information:
170
 *
171
 * When converting between timestamps on parallel timescales of differing
172
 * resolutions it is historical and scientific practice to round down rather
173
 * than doing 4/5 rounding.
174
 *
175
 *   The date changes at midnight, not at noon.
176
 *
177
 *   Even at 15:59:59.999999999 it's not four'o'clock.
178
 *
179
 *   time_second ticks after N.999999999 not after N.4999999999
180
 */
181
 
182
static __inline void
183
bintime2timespec(const struct bintime *_bt, struct timespec *_ts)
184
{
185
 
186
	_ts->tv_sec = _bt->sec;
187
	_ts->tv_nsec = ((uint64_t)1000000000 *
188
	    (uint32_t)(_bt->frac >> 32)) >> 32;
189
}
190
 
191
static __inline void
192
timespec2bintime(const struct timespec *_ts, struct bintime *_bt)
193
{
194
 
195
	_bt->sec = _ts->tv_sec;
196
	/* 18446744073 = int(2^64 / 1000000000) */
197
	_bt->frac = _ts->tv_nsec * (uint64_t)18446744073LL;
198
}
199
 
200
static __inline void
201
bintime2timeval(const struct bintime *_bt, struct timeval *_tv)
202
{
203
 
204
	_tv->tv_sec = _bt->sec;
205
	_tv->tv_usec = ((uint64_t)1000000 * (uint32_t)(_bt->frac >> 32)) >> 32;
206
}
207
 
208
static __inline void
209
timeval2bintime(const struct timeval *_tv, struct bintime *_bt)
210
{
211
 
212
	_bt->sec = _tv->tv_sec;
213
	/* 18446744073709 = int(2^64 / 1000000) */
214
	_bt->frac = _tv->tv_usec * (uint64_t)18446744073709LL;
215
}
216
 
217
static __inline struct timespec
218
sbttots(sbintime_t _sbt)
219
{
220
	struct timespec _ts;
221
 
222
	_ts.tv_sec = _sbt >> 32;
223
	_ts.tv_nsec = ((uint64_t)1000000000 * (uint32_t)_sbt) >> 32;
224
	return (_ts);
225
}
226
 
227
static __inline sbintime_t
228
tstosbt(struct timespec _ts)
229
{
230
 
231
	return (((sbintime_t)_ts.tv_sec << 32) +
232
	    (_ts.tv_nsec * (((uint64_t)1 << 63) / 500000000) >> 32));
233
}
234
 
235
static __inline struct timeval
236
sbttotv(sbintime_t _sbt)
237
{
238
	struct timeval _tv;
239
 
240
	_tv.tv_sec = _sbt >> 32;
241
	_tv.tv_usec = ((uint64_t)1000000 * (uint32_t)_sbt) >> 32;
242
	return (_tv);
243
}
244
 
245
static __inline sbintime_t
246
tvtosbt(struct timeval _tv)
247
{
248
 
249
	return (((sbintime_t)_tv.tv_sec << 32) +
250
	    (_tv.tv_usec * (((uint64_t)1 << 63) / 500000) >> 32));
251
}
252
#endif /* __BSD_VISIBLE */
253
 
254
#ifdef _KERNEL
255
 
256
/* Operations on timespecs */
257
#define	timespecclear(tvp)	((tvp)->tv_sec = (tvp)->tv_nsec = 0)
258
#define	timespecisset(tvp)	((tvp)->tv_sec || (tvp)->tv_nsec)
259
#define	timespeccmp(tvp, uvp, cmp)					\
260
	(((tvp)->tv_sec == (uvp)->tv_sec) ?				\
261
	    ((tvp)->tv_nsec cmp (uvp)->tv_nsec) :			\
262
	    ((tvp)->tv_sec cmp (uvp)->tv_sec))
263
#define	timespecadd(vvp, uvp)						\
264
	do {								\
265
		(vvp)->tv_sec += (uvp)->tv_sec;				\
266
		(vvp)->tv_nsec += (uvp)->tv_nsec;			\
267
		if ((vvp)->tv_nsec >= 1000000000) {			\
268
			(vvp)->tv_sec++;				\
269
			(vvp)->tv_nsec -= 1000000000;			\
270
		}							\
271
	} while (0)
272
#define	timespecsub(vvp, uvp)						\
273
	do {								\
274
		(vvp)->tv_sec -= (uvp)->tv_sec;				\
275
		(vvp)->tv_nsec -= (uvp)->tv_nsec;			\
276
		if ((vvp)->tv_nsec < 0) {				\
277
			(vvp)->tv_sec--;				\
278
			(vvp)->tv_nsec += 1000000000;			\
279
		}							\
280
	} while (0)
281
 
282
/* Operations on timevals. */
283
 
284
#define	timevalclear(tvp)		((tvp)->tv_sec = (tvp)->tv_usec = 0)
285
#define	timevalisset(tvp)		((tvp)->tv_sec || (tvp)->tv_usec)
286
#define	timevalcmp(tvp, uvp, cmp)					\
287
	(((tvp)->tv_sec == (uvp)->tv_sec) ?				\
288
	    ((tvp)->tv_usec cmp (uvp)->tv_usec) :			\
289
	    ((tvp)->tv_sec cmp (uvp)->tv_sec))
290
 
291
/* timevaladd and timevalsub are not inlined */
292
 
293
#endif /* _KERNEL */
294
 
295
/*
296
 * Names of the interval timers, and structure
297
 * defining a timer setting.
298
 */
299
#define	ITIMER_REAL	0
300
#define	ITIMER_VIRTUAL	1
301
#define	ITIMER_PROF	2
302
 
303
struct itimerval {
304
	struct	timeval it_interval;	/* timer interval */
305
	struct	timeval it_value;	/* current value */
4921 Serge 306
};
307
 
6099 serge 308
#ifdef _KERNEL
309
 
310
/*
311
 * Kernel to clock driver interface.
312
 */
313
void	inittodr(time_t base);
314
void	resettodr(void);
315
 
316
extern volatile time_t	time_second;
317
extern volatile time_t	time_uptime;
318
extern struct bintime boottimebin;
319
extern struct timeval boottime;
320
extern struct bintime tc_tick_bt;
321
extern sbintime_t tc_tick_sbt;
322
extern struct bintime tick_bt;
323
extern sbintime_t tick_sbt;
324
extern int tc_precexp;
325
extern int tc_timepercentage;
326
extern struct bintime bt_timethreshold;
327
extern struct bintime bt_tickthreshold;
328
extern sbintime_t sbt_timethreshold;
329
extern sbintime_t sbt_tickthreshold;
330
 
331
/*
332
 * Functions for looking at our clock: [get]{bin,nano,micro}[up]time()
333
 *
334
 * Functions without the "get" prefix returns the best timestamp
335
 * we can produce in the given format.
336
 *
337
 * "bin"   == struct bintime  == seconds + 64 bit fraction of seconds.
338
 * "nano"  == struct timespec == seconds + nanoseconds.
339
 * "micro" == struct timeval  == seconds + microseconds.
340
 *
341
 * Functions containing "up" returns time relative to boot and
342
 * should be used for calculating time intervals.
343
 *
344
 * Functions without "up" returns UTC time.
345
 *
346
 * Functions with the "get" prefix returns a less precise result
347
 * much faster than the functions without "get" prefix and should
348
 * be used where a precision of 1/hz seconds is acceptable or where
349
 * performance is priority. (NB: "precision", _not_ "resolution" !)
350
 */
351
 
352
void	binuptime(struct bintime *bt);
353
void	nanouptime(struct timespec *tsp);
354
void	microuptime(struct timeval *tvp);
355
 
356
static __inline sbintime_t
357
sbinuptime(void)
358
{
359
	struct bintime _bt;
360
 
361
	binuptime(&_bt);
362
	return (bttosbt(_bt));
363
}
364
 
365
void	bintime(struct bintime *bt);
366
void	nanotime(struct timespec *tsp);
367
void	microtime(struct timeval *tvp);
368
 
369
void	getbinuptime(struct bintime *bt);
370
void	getnanouptime(struct timespec *tsp);
371
void	getmicrouptime(struct timeval *tvp);
372
 
373
static __inline sbintime_t
374
getsbinuptime(void)
375
{
376
	struct bintime _bt;
377
 
378
	getbinuptime(&_bt);
379
	return (bttosbt(_bt));
380
}
381
 
382
void	getbintime(struct bintime *bt);
383
void	getnanotime(struct timespec *tsp);
384
void	getmicrotime(struct timeval *tvp);
385
 
386
/* Other functions */
387
int	itimerdecr(struct itimerval *itp, int usec);
388
int	itimerfix(struct timeval *tv);
389
int	ppsratecheck(struct timeval *, int *, int);
390
int	ratecheck(struct timeval *, const struct timeval *);
391
void	timevaladd(struct timeval *t1, const struct timeval *t2);
392
void	timevalsub(struct timeval *t1, const struct timeval *t2);
393
int	tvtohz(struct timeval *tv);
394
 
395
#define	TC_DEFAULTPERC		5
396
 
397
#define	BT2FREQ(bt)                                                     \
398
	(((uint64_t)0x8000000000000000 + ((bt)->frac >> 2)) /           \
399
	    ((bt)->frac >> 1))
400
 
401
#define	SBT2FREQ(sbt)	((SBT_1S + ((sbt) >> 1)) / (sbt))
402
 
403
#define	FREQ2BT(freq, bt)                                               \
404
{									\
405
	(bt)->sec = 0;                                                  \
406
	(bt)->frac = ((uint64_t)0x8000000000000000  / (freq)) << 1;     \
407
}
408
 
409
#define	TIMESEL(sbt, sbt2)						\
410
	(((sbt2) >= sbt_timethreshold) ?				\
411
	    ((*(sbt) = getsbinuptime()), 1) : ((*(sbt) = sbinuptime()), 0))
412
 
413
#else /* !_KERNEL */
414
#include 
415
 
416
#include 
417
 
418
__BEGIN_DECLS
419
int _EXFUN(setitimer, (int __which, const struct itimerval *__restrict __value,
420
					struct itimerval *__restrict __ovalue));
421
int _EXFUN(utimes, (const char *__path, const struct timeval *__tvp));
422
 
423
#if __BSD_VISIBLE
424
int _EXFUN(adjtime, (const struct timeval *, struct timeval *));
425
int _EXFUN(futimes, (int, const struct timeval *));
426
int _EXFUN(futimesat, (int, const char *, const struct timeval [2]));
427
int _EXFUN(lutimes, (const char *, const struct timeval *));
428
int _EXFUN(settimeofday, (const struct timeval *, const struct timezone *));
4921 Serge 429
#endif
430
 
6099 serge 431
#if __XSI_VISIBLE
432
int _EXFUN(getitimer, (int __which, struct itimerval *__value));
4921 Serge 433
int _EXFUN(gettimeofday, (struct timeval *__restrict __p,
434
			  void *__restrict __tz));
6099 serge 435
#endif
4349 Serge 436
 
6099 serge 437
#ifdef _COMPILING_NEWLIB
438
int _EXFUN(_gettimeofday, (struct timeval *__p, void *__tz));
4349 Serge 439
#endif
6099 serge 440
 
441
__END_DECLS
442
 
443
#endif /* !_KERNEL */
444
 
445
#endif /* !_SYS_TIME_H_ */