1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-24 07:20:37 +00:00
emacs/lib/timespec.h

135 lines
4.1 KiB
C
Raw Normal View History

/* timespec -- System time interface
Copyright (C) 2000, 2002, 2004-2005, 2007, 2009-2018 Free Software
Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
#if ! defined TIMESPEC_H
# define TIMESPEC_H
# include <time.h>
#ifndef _GL_INLINE_HEADER_BEGIN
#error "Please include config.h first."
#endif
_GL_INLINE_HEADER_BEGIN
#ifndef _GL_TIMESPEC_INLINE
# define _GL_TIMESPEC_INLINE _GL_INLINE
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include "verify.h"
/* Inverse resolution of timespec timestamps (in units per second),
and log base 10 of the inverse resolution. */
Simplify EMACS_TIME-related code. This portability layer is no longer needed, since Emacs has been using struct timespec as a portability layer for some time. Merge from gnulib, incorporating: 2013-08-27 timespec: new convenience constants and function * src/atimer.h, src/buffer.h, src/dispextern.h, src/xgselect.h: Include <time.h> rather than "systime.h"; that's all that's needed now. * src/dispnew.c: Include <timespec.h> rather than "systime.h"; that's all that's needed now. * src/systime.h (EMACS_TIME): Remove. All uses changed to struct timespec. (EMACS_TIME_RESOLUTION): Remove. All uses changed to TIMESPEC_RESOLUTION. (LOG10_EMACS_TIME_RESOLUTION): Remove. All uses changed to LOG10_TIMESPEC_RESOLUTION. (EMACS_SECS, emacs_secs_addr): Remove. All uses changed to tv_sec. (EMACS_NSECS): Remove. All uses changed to tv_nsec. (make_emacs_time): Remove. All used changed to make_timespec. (invalid_timespec): Rename from invalid_emacs_time. All uses changed. (current_timespec): Rename from current_emacs_time. All uses changed. (add_emacs_time): Remove. All uses changed to timespec_add. (sub_emacs_time): Remove. All uses change dot timespec_sub. (EMACS_TIME_SIGN): Remove. All uses changed to timespec_sign. (timespec_valid_p): Rename from EMACS_TIME_VALID_P. All uses changed. (EMACS_TIME_FROM_DOUBLE): Remove. All uses changed to dtotimespec. (EMACS_TIME_TO_DOUBLE): Remove. All uses changed to timespectod. (current_timespec): Rename from current_emacs_time. All uses changed. (EMACS_TIME_EQ, EMACS_TIME_LT, EMACS_TIME_LE): Remove. All uses changed to timespec_cmp. * src/xgselect.c: Include <timespec.h>, since our .h files don't.
2013-08-27 18:47:55 +00:00
enum { TIMESPEC_HZ = 1000000000 };
enum { LOG10_TIMESPEC_HZ = 9 };
/* Obsolescent names for backward compatibility.
They are misnomers, because TIMESPEC_RESOLUTION is not a resolution. */
enum { TIMESPEC_RESOLUTION = TIMESPEC_HZ };
enum { LOG10_TIMESPEC_RESOLUTION = LOG10_TIMESPEC_HZ };
Simplify EMACS_TIME-related code. This portability layer is no longer needed, since Emacs has been using struct timespec as a portability layer for some time. Merge from gnulib, incorporating: 2013-08-27 timespec: new convenience constants and function * src/atimer.h, src/buffer.h, src/dispextern.h, src/xgselect.h: Include <time.h> rather than "systime.h"; that's all that's needed now. * src/dispnew.c: Include <timespec.h> rather than "systime.h"; that's all that's needed now. * src/systime.h (EMACS_TIME): Remove. All uses changed to struct timespec. (EMACS_TIME_RESOLUTION): Remove. All uses changed to TIMESPEC_RESOLUTION. (LOG10_EMACS_TIME_RESOLUTION): Remove. All uses changed to LOG10_TIMESPEC_RESOLUTION. (EMACS_SECS, emacs_secs_addr): Remove. All uses changed to tv_sec. (EMACS_NSECS): Remove. All uses changed to tv_nsec. (make_emacs_time): Remove. All used changed to make_timespec. (invalid_timespec): Rename from invalid_emacs_time. All uses changed. (current_timespec): Rename from current_emacs_time. All uses changed. (add_emacs_time): Remove. All uses changed to timespec_add. (sub_emacs_time): Remove. All uses change dot timespec_sub. (EMACS_TIME_SIGN): Remove. All uses changed to timespec_sign. (timespec_valid_p): Rename from EMACS_TIME_VALID_P. All uses changed. (EMACS_TIME_FROM_DOUBLE): Remove. All uses changed to dtotimespec. (EMACS_TIME_TO_DOUBLE): Remove. All uses changed to timespectod. (current_timespec): Rename from current_emacs_time. All uses changed. (EMACS_TIME_EQ, EMACS_TIME_LT, EMACS_TIME_LE): Remove. All uses changed to timespec_cmp. * src/xgselect.c: Include <timespec.h>, since our .h files don't.
2013-08-27 18:47:55 +00:00
/* Return a timespec with seconds S and nanoseconds NS. */
_GL_TIMESPEC_INLINE struct timespec
make_timespec (time_t s, long int ns)
{
struct timespec r;
r.tv_sec = s;
r.tv_nsec = ns;
return r;
}
/* Return negative, zero, positive if A < B, A == B, A > B, respectively.
For each timestamp T, this code assumes that either:
* T.tv_nsec is in the range 0..999999999; or
* T.tv_sec corresponds to a valid leap second on a host that supports
leap seconds, and T.tv_nsec is in the range 1000000000..1999999999; or
* T.tv_sec is the minimum time_t value and T.tv_nsec is -1; or
T.tv_sec is the maximum time_t value and T.tv_nsec is 2000000000.
This allows for special struct timespec values that are less or
greater than all possible valid timestamps.
In all these cases, it is safe to subtract two tv_nsec values and
convert the result to integer without worrying about overflow on
any platform of interest to the GNU project, since all such
platforms have 32-bit int or wider.
Replacing "a.tv_nsec - b.tv_nsec" with something like
"a.tv_nsec < b.tv_nsec ? -1 : a.tv_nsec > b.tv_nsec" would cause
this function to work in some cases where the above assumption is
violated, but not in all cases (e.g., a.tv_sec==1, a.tv_nsec==-2,
b.tv_sec==0, b.tv_nsec==999999999) and is arguably not worth the
extra instructions. Using a subtraction has the advantage of
detecting some invalid cases on platforms that detect integer
overflow. */
_GL_TIMESPEC_INLINE int _GL_ATTRIBUTE_PURE
timespec_cmp (struct timespec a, struct timespec b)
{
if (a.tv_sec < b.tv_sec)
return -1;
if (a.tv_sec > b.tv_sec)
return 1;
/* Pacify gcc -Wstrict-overflow (bleeding-edge circa 2017-10-02). See:
Update from Gnulib This incorporates: 2018-05-21 crypto: omit stream ops Emacs doesn’t need 2018-05-13 truncate: Fix compilation error on Android 2018-05-13 imaxdiv: Fix compilation error on Android 2018-05-13 Support selective inclusion of recent mingw.org headers 2018-05-13 Add cross-compilation guesses for Linux systems sans glibc 2018-05-13 stdioext: Fix compilation errors with newer Android headers 2018-05-07 af_alg: Pacify --enable-gcc-warnings 2018-05-06 af_alg: Fix bug with streams that are not at position 0 2018-05-06 Followup to 'af_alg: New module' 2018-05-05 crypto/{md5,sha1,sha256,sha512}: simplify 2018-05-05 af_alg: New module 2018-05-05 af_alg: Improve function signature 2018-04-28 md5sum: Use AF_ALG when available 2018-04-28 sha512sum: Use AF_ALG when available 2018-04-28 sha256sum: Use AF_ALG when available 2018-04-28 sha1sum: Use AF_ALG when available 2018-05-05 all: Replace more http URLs by https URLs 2018-05-03 maint: port more modules to GCC 8 2018-05-03 Simplify code; drop support for Borland C++ on Windows * admin/merge-gnulib (GNULIB_MODULES): Use crypto/md5-buffer rather than crypto/md5, since Emacs doesn’t use the stream operations that in recent Gnulib pull in other stuff Emacs doesn’t need. Similarly for crypto/sha1-buffer, crypto/sha256-buffer, crypto/sha512-buffer. * build-aux/config.guess, build-aux/config.sub, lib/dosname.h: * lib/dup2.c, lib/errno.in.h, lib/euidaccess.c, lib/fcntl.c: * lib/fcntl.in.h, lib/fpending.c, lib/fsync.c, lib/getdtablesize.c: * lib/getopt.c, lib/gettimeofday.c, lib/inttypes.in.h, lib/md5.c: * lib/md5.h, lib/open.c, lib/pipe2.c, lib/putenv.c, lib/sha1.c: * lib/sha1.h, lib/sha256.c, lib/sha256.h, lib/sha512.c: * lib/sha512.h, lib/stat-time.h, lib/stdio-impl.h, lib/stdio.in.h: * lib/stdlib.in.h, lib/sys_stat.in.h, lib/sys_types.in.h: * lib/timespec.h, lib/unistd.in.h, lib/utimens.c, m4/c-strtod.m4: * m4/gnulib-common.m4, m4/inttypes.m4, m4/lstat.m4, m4/nocrash.m4: * m4/pselect.m4, m4/readlink.m4, m4/stdio_h.m4, m4/symlink.m4: * m4/unistd_h.m4, m4/utimens.m4: Copy from Gnulib. * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
2018-05-21 18:42:18 +00:00
https://lists.gnu.org/r/bug-gnulib/2017-10/msg00006.html */
assume (-1 <= a.tv_nsec && a.tv_nsec <= 2 * TIMESPEC_HZ);
assume (-1 <= b.tv_nsec && b.tv_nsec <= 2 * TIMESPEC_HZ);
return a.tv_nsec - b.tv_nsec;
}
/* Return -1, 0, 1, depending on the sign of A. A.tv_nsec must be
nonnegative. */
_GL_TIMESPEC_INLINE int _GL_ATTRIBUTE_PURE
timespec_sign (struct timespec a)
{
return a.tv_sec < 0 ? -1 : a.tv_sec || a.tv_nsec;
}
2012-07-09 08:34:39 +00:00
struct timespec timespec_add (struct timespec, struct timespec)
_GL_ATTRIBUTE_CONST;
struct timespec timespec_sub (struct timespec, struct timespec)
_GL_ATTRIBUTE_CONST;
struct timespec dtotimespec (double)
_GL_ATTRIBUTE_CONST;
/* Return an approximation to A, of type 'double'. */
_GL_TIMESPEC_INLINE double
timespectod (struct timespec a)
{
return a.tv_sec + a.tv_nsec / 1e9;
}
void gettime (struct timespec *);
int settime (struct timespec const *);
#ifdef __cplusplus
}
#endif
_GL_INLINE_HEADER_END
#endif