2000-02-18 03:39:52 +08:00
|
|
|
/* time.h -- An implementation of the standard Unix <sys/time.h> file.
|
|
|
|
Written by Geoffrey Noer <noer@cygnus.com>
|
|
|
|
Public domain; no rights reserved. */
|
|
|
|
|
2015-03-13 20:17:34 +08:00
|
|
|
/*-
|
2017-11-21 03:43:44 +08:00
|
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
*
|
2015-03-13 20:17:34 +08:00
|
|
|
* Copyright (c) 1982, 1986, 1993
|
|
|
|
* The Regents of the University of California. All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
2017-03-01 07:42:47 +08:00
|
|
|
* 3. Neither the name of the University nor the names of its contributors
|
2015-03-13 20:17:34 +08:00
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
* @(#)time.h 8.5 (Berkeley) 5/4/95
|
Ensure that all values of ns, us and ms work
for {n,u,m}stosbt
Integer overflows and wrong constants limited the accuracy of these
functions and created situatiosn where sbttoXs(Xstosbt(Y)) != Y. This
was especailly true in the ns case where we had millions of values
that were wrong.
Instead, used fixed constants because there's no way to say ceil(X)
for integer math. Document what these crazy constants are.
Also, use a shift one fewer left to avoid integer overflow causing
incorrect results, and adjust the equasion accordingly. Document this.
Allow times >= 1s to be well defined for these conversion functions
(at least the Xstosbt). There's too many users in the tree that they
work for >= 1s.
This fixes a failure on boot to program firmware on the mlx4
NIC. There was a msleep(1000) in the code. Prior to my recent rounding
changes, msleep(1000) worked, but msleep(1001) did not because the old
code rounded to just below 2^64 and the new code rounds to just above
it (overflowing, causing the msleep(1000) to really sleep 1ms).
A test program to test all cases will be committed shortly. The test
exaustively tries every value (thanks to bde for the test).
Sponsored by: Netflix, Inc
Differential Revision: https://reviews.freebsd.org/D18051
2018-11-20 15:11:23 +08:00
|
|
|
* $FreeBSD: head/sys/sys/time.h 340664 2018-11-20 07:11:23Z imp $
|
2015-03-13 20:17:34 +08:00
|
|
|
*/
|
|
|
|
|
2000-02-18 03:39:52 +08:00
|
|
|
#ifndef _SYS_TIME_H_
|
2015-03-13 20:17:34 +08:00
|
|
|
#define _SYS_TIME_H_
|
2000-02-18 03:39:52 +08:00
|
|
|
|
|
|
|
#include <_ansi.h>
|
2015-07-06 20:08:30 +08:00
|
|
|
#include <sys/cdefs.h>
|
2015-03-13 20:17:34 +08:00
|
|
|
#include <sys/_timeval.h>
|
2000-02-18 03:39:52 +08:00
|
|
|
#include <sys/types.h>
|
2015-03-13 20:17:34 +08:00
|
|
|
#include <sys/timespec.h>
|
2000-02-18 03:39:52 +08:00
|
|
|
|
2016-03-15 10:14:39 +08:00
|
|
|
#if __BSD_VISIBLE || __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE
|
2015-05-02 21:07:44 +08:00
|
|
|
#include <sys/select.h>
|
2015-12-14 17:06:18 +08:00
|
|
|
#endif
|
2015-05-02 21:07:44 +08:00
|
|
|
|
2015-03-13 20:17:34 +08:00
|
|
|
struct timezone {
|
|
|
|
int tz_minuteswest; /* minutes west of Greenwich */
|
|
|
|
int tz_dsttime; /* type of dst correction */
|
|
|
|
};
|
|
|
|
#define DST_NONE 0 /* not on dst */
|
|
|
|
#define DST_USA 1 /* USA style dst */
|
|
|
|
#define DST_AUST 2 /* Australian style dst */
|
|
|
|
#define DST_WET 3 /* Western European dst */
|
|
|
|
#define DST_MET 4 /* Middle European dst */
|
|
|
|
#define DST_EET 5 /* Eastern European dst */
|
|
|
|
#define DST_CAN 6 /* Canada */
|
2000-02-18 03:39:52 +08:00
|
|
|
|
2015-03-13 20:17:34 +08:00
|
|
|
#if __BSD_VISIBLE
|
|
|
|
struct bintime {
|
|
|
|
time_t sec;
|
2015-04-02 02:34:08 +08:00
|
|
|
uint64_t frac;
|
2000-02-18 03:39:52 +08:00
|
|
|
};
|
|
|
|
|
2015-03-13 20:17:34 +08:00
|
|
|
static __inline void
|
2015-04-02 02:34:08 +08:00
|
|
|
bintime_addx(struct bintime *_bt, uint64_t _x)
|
2015-03-13 20:17:34 +08:00
|
|
|
{
|
2015-04-02 02:34:08 +08:00
|
|
|
uint64_t _u;
|
2012-11-12 23:57:35 +08:00
|
|
|
|
2015-03-13 20:17:34 +08:00
|
|
|
_u = _bt->frac;
|
|
|
|
_bt->frac += _x;
|
|
|
|
if (_u > _bt->frac)
|
|
|
|
_bt->sec++;
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline void
|
|
|
|
bintime_add(struct bintime *_bt, const struct bintime *_bt2)
|
|
|
|
{
|
2015-04-02 02:34:08 +08:00
|
|
|
uint64_t _u;
|
2015-03-13 20:17:34 +08:00
|
|
|
|
|
|
|
_u = _bt->frac;
|
|
|
|
_bt->frac += _bt2->frac;
|
|
|
|
if (_u > _bt->frac)
|
|
|
|
_bt->sec++;
|
|
|
|
_bt->sec += _bt2->sec;
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline void
|
|
|
|
bintime_sub(struct bintime *_bt, const struct bintime *_bt2)
|
|
|
|
{
|
2015-04-02 02:34:08 +08:00
|
|
|
uint64_t _u;
|
2015-03-13 20:17:34 +08:00
|
|
|
|
|
|
|
_u = _bt->frac;
|
|
|
|
_bt->frac -= _bt2->frac;
|
|
|
|
if (_u < _bt->frac)
|
|
|
|
_bt->sec--;
|
|
|
|
_bt->sec -= _bt2->sec;
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline void
|
|
|
|
bintime_mul(struct bintime *_bt, u_int _x)
|
|
|
|
{
|
2015-04-02 02:34:08 +08:00
|
|
|
uint64_t _p1, _p2;
|
2015-03-13 20:17:34 +08:00
|
|
|
|
|
|
|
_p1 = (_bt->frac & 0xffffffffull) * _x;
|
|
|
|
_p2 = (_bt->frac >> 32) * _x + (_p1 >> 32);
|
|
|
|
_bt->sec *= _x;
|
|
|
|
_bt->sec += (_p2 >> 32);
|
|
|
|
_bt->frac = (_p2 << 32) | (_p1 & 0xffffffffull);
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline void
|
|
|
|
bintime_shift(struct bintime *_bt, int _exp)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (_exp > 0) {
|
|
|
|
_bt->sec <<= _exp;
|
|
|
|
_bt->sec |= _bt->frac >> (64 - _exp);
|
|
|
|
_bt->frac <<= _exp;
|
|
|
|
} else if (_exp < 0) {
|
|
|
|
_bt->frac >>= -_exp;
|
2015-04-02 02:34:08 +08:00
|
|
|
_bt->frac |= (uint64_t)_bt->sec << (64 + _exp);
|
2015-03-13 20:17:34 +08:00
|
|
|
_bt->sec >>= -_exp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#define bintime_clear(a) ((a)->sec = (a)->frac = 0)
|
|
|
|
#define bintime_isset(a) ((a)->sec || (a)->frac)
|
|
|
|
#define bintime_cmp(a, b, cmp) \
|
|
|
|
(((a)->sec == (b)->sec) ? \
|
|
|
|
((a)->frac cmp (b)->frac) : \
|
|
|
|
((a)->sec cmp (b)->sec))
|
|
|
|
|
|
|
|
#define SBT_1S ((sbintime_t)1 << 32)
|
|
|
|
#define SBT_1M (SBT_1S * 60)
|
|
|
|
#define SBT_1MS (SBT_1S / 1000)
|
|
|
|
#define SBT_1US (SBT_1S / 1000000)
|
2017-07-30 01:00:23 +08:00
|
|
|
#define SBT_1NS (SBT_1S / 1000000000) /* beware rounding, see nstosbt() */
|
2015-03-13 20:17:34 +08:00
|
|
|
#define SBT_MAX 0x7fffffffffffffffLL
|
|
|
|
|
|
|
|
static __inline int
|
|
|
|
sbintime_getsec(sbintime_t _sbt)
|
|
|
|
{
|
|
|
|
|
|
|
|
return (_sbt >> 32);
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline sbintime_t
|
|
|
|
bttosbt(const struct bintime _bt)
|
|
|
|
{
|
|
|
|
|
|
|
|
return (((sbintime_t)_bt.sec << 32) + (_bt.frac >> 32));
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline struct bintime
|
|
|
|
sbttobt(sbintime_t _sbt)
|
|
|
|
{
|
|
|
|
struct bintime _bt;
|
|
|
|
|
|
|
|
_bt.sec = _sbt >> 32;
|
|
|
|
_bt.frac = _sbt << 32;
|
|
|
|
return (_bt);
|
|
|
|
}
|
|
|
|
|
2017-07-30 01:00:23 +08:00
|
|
|
/*
|
|
|
|
* Decimal<->sbt conversions. Multiplying or dividing by SBT_1NS results in
|
|
|
|
* large roundoff errors which sbttons() and nstosbt() avoid. Millisecond and
|
|
|
|
* microsecond functions are also provided for completeness.
|
2018-11-16 00:02:13 +08:00
|
|
|
*
|
Ensure that all values of ns, us and ms work
for {n,u,m}stosbt
Integer overflows and wrong constants limited the accuracy of these
functions and created situatiosn where sbttoXs(Xstosbt(Y)) != Y. This
was especailly true in the ns case where we had millions of values
that were wrong.
Instead, used fixed constants because there's no way to say ceil(X)
for integer math. Document what these crazy constants are.
Also, use a shift one fewer left to avoid integer overflow causing
incorrect results, and adjust the equasion accordingly. Document this.
Allow times >= 1s to be well defined for these conversion functions
(at least the Xstosbt). There's too many users in the tree that they
work for >= 1s.
This fixes a failure on boot to program firmware on the mlx4
NIC. There was a msleep(1000) in the code. Prior to my recent rounding
changes, msleep(1000) worked, but msleep(1001) did not because the old
code rounded to just below 2^64 and the new code rounds to just above
it (overflowing, causing the msleep(1000) to really sleep 1ms).
A test program to test all cases will be committed shortly. The test
exaustively tries every value (thanks to bde for the test).
Sponsored by: Netflix, Inc
Differential Revision: https://reviews.freebsd.org/D18051
2018-11-20 15:11:23 +08:00
|
|
|
* These functions return the smallest sbt larger or equal to the
|
|
|
|
* number of seconds requested so that sbttoX(Xtosbt(y)) == y. Unlike
|
|
|
|
* top of second computations below, which require that we tick at the
|
|
|
|
* top of second, these need to be rounded up so we do whatever for at
|
|
|
|
* least as long as requested.
|
|
|
|
*
|
|
|
|
* The naive computation we'd do is this
|
|
|
|
* ((unit * 2^64 / SIFACTOR) + 2^32-1) >> 32
|
|
|
|
* However, that overflows. Instead, we compute
|
|
|
|
* ((unit * 2^63 / SIFACTOR) + 2^31-1) >> 32
|
|
|
|
* and use pre-computed constants that are the ceil of the 2^63 / SIFACTOR
|
|
|
|
* term to ensure we are using exactly the right constant. We use the lesser
|
|
|
|
* evil of ull rather than a uint64_t cast to ensure we have well defined
|
|
|
|
* right shift semantics. With these changes, we get all the ns, us and ms
|
|
|
|
* conversions back and forth right.
|
2017-07-30 01:00:23 +08:00
|
|
|
*/
|
|
|
|
static __inline int64_t
|
|
|
|
sbttons(sbintime_t _sbt)
|
|
|
|
{
|
|
|
|
|
|
|
|
return ((1000000000 * _sbt) >> 32);
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline sbintime_t
|
|
|
|
nstosbt(int64_t _ns)
|
|
|
|
{
|
Ensure that all values of ns, us and ms work
for {n,u,m}stosbt
Integer overflows and wrong constants limited the accuracy of these
functions and created situatiosn where sbttoXs(Xstosbt(Y)) != Y. This
was especailly true in the ns case where we had millions of values
that were wrong.
Instead, used fixed constants because there's no way to say ceil(X)
for integer math. Document what these crazy constants are.
Also, use a shift one fewer left to avoid integer overflow causing
incorrect results, and adjust the equasion accordingly. Document this.
Allow times >= 1s to be well defined for these conversion functions
(at least the Xstosbt). There's too many users in the tree that they
work for >= 1s.
This fixes a failure on boot to program firmware on the mlx4
NIC. There was a msleep(1000) in the code. Prior to my recent rounding
changes, msleep(1000) worked, but msleep(1001) did not because the old
code rounded to just below 2^64 and the new code rounds to just above
it (overflowing, causing the msleep(1000) to really sleep 1ms).
A test program to test all cases will be committed shortly. The test
exaustively tries every value (thanks to bde for the test).
Sponsored by: Netflix, Inc
Differential Revision: https://reviews.freebsd.org/D18051
2018-11-20 15:11:23 +08:00
|
|
|
sbintime_t sb = 0;
|
2017-07-30 01:00:23 +08:00
|
|
|
|
Ensure that all values of ns, us and ms work
for {n,u,m}stosbt
Integer overflows and wrong constants limited the accuracy of these
functions and created situatiosn where sbttoXs(Xstosbt(Y)) != Y. This
was especailly true in the ns case where we had millions of values
that were wrong.
Instead, used fixed constants because there's no way to say ceil(X)
for integer math. Document what these crazy constants are.
Also, use a shift one fewer left to avoid integer overflow causing
incorrect results, and adjust the equasion accordingly. Document this.
Allow times >= 1s to be well defined for these conversion functions
(at least the Xstosbt). There's too many users in the tree that they
work for >= 1s.
This fixes a failure on boot to program firmware on the mlx4
NIC. There was a msleep(1000) in the code. Prior to my recent rounding
changes, msleep(1000) worked, but msleep(1001) did not because the old
code rounded to just below 2^64 and the new code rounds to just above
it (overflowing, causing the msleep(1000) to really sleep 1ms).
A test program to test all cases will be committed shortly. The test
exaustively tries every value (thanks to bde for the test).
Sponsored by: Netflix, Inc
Differential Revision: https://reviews.freebsd.org/D18051
2018-11-20 15:11:23 +08:00
|
|
|
if (_ns >= SBT_1S) {
|
|
|
|
sb = (_ns / 1000000000) * SBT_1S;
|
|
|
|
_ns = _ns % 1000000000;
|
|
|
|
}
|
|
|
|
/* 9223372037 = ceil(2^63 / 1000000000) */
|
|
|
|
sb += ((_ns * 9223372037ull) + 0x7fffffff) >> 31;
|
|
|
|
return (sb);
|
2017-07-30 01:00:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static __inline int64_t
|
|
|
|
sbttous(sbintime_t _sbt)
|
|
|
|
{
|
|
|
|
|
|
|
|
return ((1000000 * _sbt) >> 32);
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline sbintime_t
|
|
|
|
ustosbt(int64_t _us)
|
|
|
|
{
|
Ensure that all values of ns, us and ms work
for {n,u,m}stosbt
Integer overflows and wrong constants limited the accuracy of these
functions and created situatiosn where sbttoXs(Xstosbt(Y)) != Y. This
was especailly true in the ns case where we had millions of values
that were wrong.
Instead, used fixed constants because there's no way to say ceil(X)
for integer math. Document what these crazy constants are.
Also, use a shift one fewer left to avoid integer overflow causing
incorrect results, and adjust the equasion accordingly. Document this.
Allow times >= 1s to be well defined for these conversion functions
(at least the Xstosbt). There's too many users in the tree that they
work for >= 1s.
This fixes a failure on boot to program firmware on the mlx4
NIC. There was a msleep(1000) in the code. Prior to my recent rounding
changes, msleep(1000) worked, but msleep(1001) did not because the old
code rounded to just below 2^64 and the new code rounds to just above
it (overflowing, causing the msleep(1000) to really sleep 1ms).
A test program to test all cases will be committed shortly. The test
exaustively tries every value (thanks to bde for the test).
Sponsored by: Netflix, Inc
Differential Revision: https://reviews.freebsd.org/D18051
2018-11-20 15:11:23 +08:00
|
|
|
sbintime_t sb = 0;
|
2017-07-30 01:00:23 +08:00
|
|
|
|
Ensure that all values of ns, us and ms work
for {n,u,m}stosbt
Integer overflows and wrong constants limited the accuracy of these
functions and created situatiosn where sbttoXs(Xstosbt(Y)) != Y. This
was especailly true in the ns case where we had millions of values
that were wrong.
Instead, used fixed constants because there's no way to say ceil(X)
for integer math. Document what these crazy constants are.
Also, use a shift one fewer left to avoid integer overflow causing
incorrect results, and adjust the equasion accordingly. Document this.
Allow times >= 1s to be well defined for these conversion functions
(at least the Xstosbt). There's too many users in the tree that they
work for >= 1s.
This fixes a failure on boot to program firmware on the mlx4
NIC. There was a msleep(1000) in the code. Prior to my recent rounding
changes, msleep(1000) worked, but msleep(1001) did not because the old
code rounded to just below 2^64 and the new code rounds to just above
it (overflowing, causing the msleep(1000) to really sleep 1ms).
A test program to test all cases will be committed shortly. The test
exaustively tries every value (thanks to bde for the test).
Sponsored by: Netflix, Inc
Differential Revision: https://reviews.freebsd.org/D18051
2018-11-20 15:11:23 +08:00
|
|
|
if (_us >= SBT_1S) {
|
|
|
|
sb = (_us / 1000000) * SBT_1S;
|
|
|
|
_us = _us % 1000000;
|
|
|
|
}
|
|
|
|
/* 9223372036855 = ceil(2^63 / 1000000) */
|
|
|
|
sb += ((_us * 9223372036855ull) + 0x7fffffff) >> 31;
|
|
|
|
return (sb);
|
2017-07-30 01:00:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static __inline int64_t
|
|
|
|
sbttoms(sbintime_t _sbt)
|
|
|
|
{
|
|
|
|
|
|
|
|
return ((1000 * _sbt) >> 32);
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline sbintime_t
|
|
|
|
mstosbt(int64_t _ms)
|
|
|
|
{
|
Ensure that all values of ns, us and ms work
for {n,u,m}stosbt
Integer overflows and wrong constants limited the accuracy of these
functions and created situatiosn where sbttoXs(Xstosbt(Y)) != Y. This
was especailly true in the ns case where we had millions of values
that were wrong.
Instead, used fixed constants because there's no way to say ceil(X)
for integer math. Document what these crazy constants are.
Also, use a shift one fewer left to avoid integer overflow causing
incorrect results, and adjust the equasion accordingly. Document this.
Allow times >= 1s to be well defined for these conversion functions
(at least the Xstosbt). There's too many users in the tree that they
work for >= 1s.
This fixes a failure on boot to program firmware on the mlx4
NIC. There was a msleep(1000) in the code. Prior to my recent rounding
changes, msleep(1000) worked, but msleep(1001) did not because the old
code rounded to just below 2^64 and the new code rounds to just above
it (overflowing, causing the msleep(1000) to really sleep 1ms).
A test program to test all cases will be committed shortly. The test
exaustively tries every value (thanks to bde for the test).
Sponsored by: Netflix, Inc
Differential Revision: https://reviews.freebsd.org/D18051
2018-11-20 15:11:23 +08:00
|
|
|
sbintime_t sb = 0;
|
2017-07-30 01:00:23 +08:00
|
|
|
|
Ensure that all values of ns, us and ms work
for {n,u,m}stosbt
Integer overflows and wrong constants limited the accuracy of these
functions and created situatiosn where sbttoXs(Xstosbt(Y)) != Y. This
was especailly true in the ns case where we had millions of values
that were wrong.
Instead, used fixed constants because there's no way to say ceil(X)
for integer math. Document what these crazy constants are.
Also, use a shift one fewer left to avoid integer overflow causing
incorrect results, and adjust the equasion accordingly. Document this.
Allow times >= 1s to be well defined for these conversion functions
(at least the Xstosbt). There's too many users in the tree that they
work for >= 1s.
This fixes a failure on boot to program firmware on the mlx4
NIC. There was a msleep(1000) in the code. Prior to my recent rounding
changes, msleep(1000) worked, but msleep(1001) did not because the old
code rounded to just below 2^64 and the new code rounds to just above
it (overflowing, causing the msleep(1000) to really sleep 1ms).
A test program to test all cases will be committed shortly. The test
exaustively tries every value (thanks to bde for the test).
Sponsored by: Netflix, Inc
Differential Revision: https://reviews.freebsd.org/D18051
2018-11-20 15:11:23 +08:00
|
|
|
if (_ms >= SBT_1S) {
|
|
|
|
sb = (_ms / 1000) * SBT_1S;
|
|
|
|
_ms = _ms % 1000;
|
|
|
|
}
|
|
|
|
/* 9223372036854776 = ceil(2^63 / 1000) */
|
|
|
|
sb += ((_ms * 9223372036854776ull) + 0x7fffffff) >> 31;
|
|
|
|
return (sb);
|
2017-07-30 01:00:23 +08:00
|
|
|
}
|
|
|
|
|
2015-03-13 20:17:34 +08:00
|
|
|
/*-
|
|
|
|
* Background information:
|
|
|
|
*
|
|
|
|
* When converting between timestamps on parallel timescales of differing
|
|
|
|
* resolutions it is historical and scientific practice to round down rather
|
|
|
|
* than doing 4/5 rounding.
|
|
|
|
*
|
|
|
|
* The date changes at midnight, not at noon.
|
|
|
|
*
|
|
|
|
* Even at 15:59:59.999999999 it's not four'o'clock.
|
|
|
|
*
|
|
|
|
* time_second ticks after N.999999999 not after N.4999999999
|
|
|
|
*/
|
|
|
|
|
|
|
|
static __inline void
|
|
|
|
bintime2timespec(const struct bintime *_bt, struct timespec *_ts)
|
|
|
|
{
|
|
|
|
|
|
|
|
_ts->tv_sec = _bt->sec;
|
2015-04-02 02:34:08 +08:00
|
|
|
_ts->tv_nsec = ((uint64_t)1000000000 *
|
|
|
|
(uint32_t)(_bt->frac >> 32)) >> 32;
|
2015-03-13 20:17:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static __inline void
|
|
|
|
timespec2bintime(const struct timespec *_ts, struct bintime *_bt)
|
|
|
|
{
|
|
|
|
|
|
|
|
_bt->sec = _ts->tv_sec;
|
|
|
|
/* 18446744073 = int(2^64 / 1000000000) */
|
2015-04-02 02:34:08 +08:00
|
|
|
_bt->frac = _ts->tv_nsec * (uint64_t)18446744073LL;
|
2015-03-13 20:17:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static __inline void
|
|
|
|
bintime2timeval(const struct bintime *_bt, struct timeval *_tv)
|
|
|
|
{
|
|
|
|
|
|
|
|
_tv->tv_sec = _bt->sec;
|
2015-04-02 02:34:08 +08:00
|
|
|
_tv->tv_usec = ((uint64_t)1000000 * (uint32_t)(_bt->frac >> 32)) >> 32;
|
2015-03-13 20:17:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static __inline void
|
|
|
|
timeval2bintime(const struct timeval *_tv, struct bintime *_bt)
|
|
|
|
{
|
|
|
|
|
|
|
|
_bt->sec = _tv->tv_sec;
|
|
|
|
/* 18446744073709 = int(2^64 / 1000000) */
|
2015-04-02 02:34:08 +08:00
|
|
|
_bt->frac = _tv->tv_usec * (uint64_t)18446744073709LL;
|
2015-03-13 20:17:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static __inline struct timespec
|
|
|
|
sbttots(sbintime_t _sbt)
|
|
|
|
{
|
|
|
|
struct timespec _ts;
|
|
|
|
|
|
|
|
_ts.tv_sec = _sbt >> 32;
|
2017-07-30 01:00:23 +08:00
|
|
|
_ts.tv_nsec = sbttons((uint32_t)_sbt);
|
2015-03-13 20:17:34 +08:00
|
|
|
return (_ts);
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline sbintime_t
|
|
|
|
tstosbt(struct timespec _ts)
|
|
|
|
{
|
|
|
|
|
2017-07-30 01:00:23 +08:00
|
|
|
return (((sbintime_t)_ts.tv_sec << 32) + nstosbt(_ts.tv_nsec));
|
2015-03-13 20:17:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static __inline struct timeval
|
|
|
|
sbttotv(sbintime_t _sbt)
|
|
|
|
{
|
|
|
|
struct timeval _tv;
|
|
|
|
|
|
|
|
_tv.tv_sec = _sbt >> 32;
|
2017-07-30 01:00:23 +08:00
|
|
|
_tv.tv_usec = sbttous((uint32_t)_sbt);
|
2015-03-13 20:17:34 +08:00
|
|
|
return (_tv);
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline sbintime_t
|
|
|
|
tvtosbt(struct timeval _tv)
|
|
|
|
{
|
|
|
|
|
2017-07-30 01:00:23 +08:00
|
|
|
return (((sbintime_t)_tv.tv_sec << 32) + ustosbt(_tv.tv_usec));
|
2015-03-13 20:17:34 +08:00
|
|
|
}
|
|
|
|
#endif /* __BSD_VISIBLE */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Names of the interval timers, and structure
|
|
|
|
* defining a timer setting.
|
|
|
|
*/
|
|
|
|
#define ITIMER_REAL 0
|
|
|
|
#define ITIMER_VIRTUAL 1
|
|
|
|
#define ITIMER_PROF 2
|
2012-11-12 23:57:35 +08:00
|
|
|
|
2015-03-13 20:17:34 +08:00
|
|
|
struct itimerval {
|
|
|
|
struct timeval it_interval; /* timer interval */
|
|
|
|
struct timeval it_value; /* current value */
|
2012-11-12 23:57:35 +08:00
|
|
|
};
|
2000-12-05 02:40:53 +08:00
|
|
|
|
2016-04-07 18:58:43 +08:00
|
|
|
#ifndef _KERNEL
|
2015-03-13 20:17:34 +08:00
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
__BEGIN_DECLS
|
2017-12-04 13:54:48 +08:00
|
|
|
int utimes (const char *__path, const struct timeval *__tvp);
|
2012-08-08 19:04:18 +08:00
|
|
|
|
2014-07-23 03:30:00 +08:00
|
|
|
#if __BSD_VISIBLE
|
2017-12-04 13:54:48 +08:00
|
|
|
int adjtime (const struct timeval *, struct timeval *);
|
|
|
|
int futimes (int, const struct timeval *);
|
|
|
|
int lutimes (const char *, const struct timeval *);
|
|
|
|
int settimeofday (const struct timeval *, const struct timezone *);
|
2014-07-23 03:30:00 +08:00
|
|
|
#endif
|
2015-03-13 20:17:34 +08:00
|
|
|
|
2016-03-15 10:14:39 +08:00
|
|
|
#if __MISC_VISIBLE || __XSI_VISIBLE
|
2017-12-04 13:54:48 +08:00
|
|
|
int getitimer (int __which, struct itimerval *__value);
|
|
|
|
int setitimer (int __which, const struct itimerval *__restrict __value,
|
|
|
|
struct itimerval *__restrict __ovalue);
|
2016-06-20 16:11:24 +08:00
|
|
|
#endif
|
|
|
|
|
2017-12-04 13:54:48 +08:00
|
|
|
int gettimeofday (struct timeval *__restrict __p,
|
|
|
|
void *__restrict __tz);
|
2000-02-18 03:39:52 +08:00
|
|
|
|
2016-03-15 10:14:39 +08:00
|
|
|
#if __GNU_VISIBLE
|
2017-12-04 13:54:48 +08:00
|
|
|
int futimesat (int, const char *, const struct timeval [2]);
|
2016-03-15 10:14:39 +08:00
|
|
|
#endif
|
|
|
|
|
2015-03-13 20:17:34 +08:00
|
|
|
#ifdef _COMPILING_NEWLIB
|
2017-12-04 13:54:48 +08:00
|
|
|
int _gettimeofday (struct timeval *__p, void *__tz);
|
2000-02-18 03:39:52 +08:00
|
|
|
#endif
|
2015-03-13 20:17:34 +08:00
|
|
|
|
|
|
|
__END_DECLS
|
|
|
|
|
|
|
|
#endif /* !_KERNEL */
|
2016-04-07 18:58:43 +08:00
|
|
|
#include <machine/_time.h>
|
2015-03-13 20:17:34 +08:00
|
|
|
|
|
|
|
#endif /* !_SYS_TIME_H_ */
|