Blame src/gl/timespec.h

Packit Service 4684c1
/* timespec -- System time interface
Packit Service 4684c1
Packit Service 4684c1
   Copyright (C) 2000, 2002, 2004-2005, 2007, 2009-2020 Free Software
Packit Service 4684c1
   Foundation, Inc.
Packit Service 4684c1
Packit Service 4684c1
   This program is free software: you can redistribute it and/or modify
Packit Service 4684c1
   it under the terms of the GNU General Public License as published by
Packit Service 4684c1
   the Free Software Foundation; either version 3 of the License, or
Packit Service 4684c1
   (at your option) any later version.
Packit Service 4684c1
Packit Service 4684c1
   This program is distributed in the hope that it will be useful,
Packit Service 4684c1
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 4684c1
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 4684c1
   GNU General Public License for more details.
Packit Service 4684c1
Packit Service 4684c1
   You should have received a copy of the GNU General Public License
Packit Service 4684c1
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
Packit Service 4684c1
Packit Service 4684c1
#if ! defined TIMESPEC_H
Packit Service 4684c1
#define TIMESPEC_H
Packit Service 4684c1
Packit Service 4684c1
#include <time.h>
Packit Service 4684c1
Packit Service 4684c1
#ifndef _GL_INLINE_HEADER_BEGIN
Packit Service 4684c1
 #error "Please include config.h first."
Packit Service 4684c1
#endif
Packit Service 4684c1
_GL_INLINE_HEADER_BEGIN
Packit Service 4684c1
#ifndef _GL_TIMESPEC_INLINE
Packit Service 4684c1
# define _GL_TIMESPEC_INLINE _GL_INLINE
Packit Service 4684c1
#endif
Packit Service 4684c1
Packit Service 4684c1
#ifdef __cplusplus
Packit Service 4684c1
extern "C" {
Packit Service 4684c1
#endif
Packit Service 4684c1
Packit Service 4684c1
#include "arg-nonnull.h"
Packit Service 4684c1
#include "verify.h"
Packit Service 4684c1
Packit Service 4684c1
/* Inverse resolution of timespec timestamps (in units per second),
Packit Service 4684c1
   and log base 10 of the inverse resolution.  */
Packit Service 4684c1
Packit Service 4684c1
enum { TIMESPEC_HZ = 1000000000 };
Packit Service 4684c1
enum { LOG10_TIMESPEC_HZ = 9 };
Packit Service 4684c1
Packit Service 4684c1
/* Obsolescent names for backward compatibility.
Packit Service 4684c1
   They are misnomers, because TIMESPEC_RESOLUTION is not a resolution.  */
Packit Service 4684c1
Packit Service 4684c1
enum { TIMESPEC_RESOLUTION = TIMESPEC_HZ };
Packit Service 4684c1
enum { LOG10_TIMESPEC_RESOLUTION = LOG10_TIMESPEC_HZ };
Packit Service 4684c1
Packit Service 4684c1
/* Return a timespec with seconds S and nanoseconds NS.  */
Packit Service 4684c1
Packit Service 4684c1
_GL_TIMESPEC_INLINE struct timespec
Packit Service 4684c1
make_timespec (time_t s, long int ns)
Packit Service 4684c1
{
Packit Service 4684c1
  struct timespec r;
Packit Service 4684c1
  r.tv_sec = s;
Packit Service 4684c1
  r.tv_nsec = ns;
Packit Service 4684c1
  return r;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/* Return negative, zero, positive if A < B, A == B, A > B, respectively.
Packit Service 4684c1
Packit Service 4684c1
   For each timestamp T, this code assumes that either:
Packit Service 4684c1
Packit Service 4684c1
     * T.tv_nsec is in the range 0..999999999; or
Packit Service 4684c1
     * T.tv_sec corresponds to a valid leap second on a host that supports
Packit Service 4684c1
       leap seconds, and T.tv_nsec is in the range 1000000000..1999999999; or
Packit Service 4684c1
     * T.tv_sec is the minimum time_t value and T.tv_nsec is -1; or
Packit Service 4684c1
       T.tv_sec is the maximum time_t value and T.tv_nsec is 2000000000.
Packit Service 4684c1
       This allows for special struct timespec values that are less or
Packit Service 4684c1
       greater than all possible valid timestamps.
Packit Service 4684c1
Packit Service 4684c1
   In all these cases, it is safe to subtract two tv_nsec values and
Packit Service 4684c1
   convert the result to integer without worrying about overflow on
Packit Service 4684c1
   any platform of interest to the GNU project, since all such
Packit Service 4684c1
   platforms have 32-bit int or wider.
Packit Service 4684c1
Packit Service 4684c1
   Replacing "a.tv_nsec - b.tv_nsec" with something like
Packit Service 4684c1
   "a.tv_nsec < b.tv_nsec ? -1 : a.tv_nsec > b.tv_nsec" would cause
Packit Service 4684c1
   this function to work in some cases where the above assumption is
Packit Service 4684c1
   violated, but not in all cases (e.g., a.tv_sec==1, a.tv_nsec==-2,
Packit Service 4684c1
   b.tv_sec==0, b.tv_nsec==999999999) and is arguably not worth the
Packit Service 4684c1
   extra instructions.  Using a subtraction has the advantage of
Packit Service 4684c1
   detecting some invalid cases on platforms that detect integer
Packit Service 4684c1
   overflow.  */
Packit Service 4684c1
Packit Service 4684c1
_GL_TIMESPEC_INLINE int _GL_ATTRIBUTE_PURE
Packit Service 4684c1
timespec_cmp (struct timespec a, struct timespec b)
Packit Service 4684c1
{
Packit Service 4684c1
  if (a.tv_sec < b.tv_sec)
Packit Service 4684c1
    return -1;
Packit Service 4684c1
  if (a.tv_sec > b.tv_sec)
Packit Service 4684c1
    return 1;
Packit Service 4684c1
Packit Service 4684c1
  /* Pacify gcc -Wstrict-overflow (bleeding-edge circa 2017-10-02).  See:
Packit Service 4684c1
     https://lists.gnu.org/r/bug-gnulib/2017-10/msg00006.html  */
Packit Service 4684c1
  assume (-1 <= a.tv_nsec && a.tv_nsec <= 2 * TIMESPEC_HZ);
Packit Service 4684c1
  assume (-1 <= b.tv_nsec && b.tv_nsec <= 2 * TIMESPEC_HZ);
Packit Service 4684c1
Packit Service 4684c1
  return a.tv_nsec - b.tv_nsec;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
/* Return -1, 0, 1, depending on the sign of A.  A.tv_nsec must be
Packit Service 4684c1
   nonnegative.  */
Packit Service 4684c1
_GL_TIMESPEC_INLINE int _GL_ATTRIBUTE_PURE
Packit Service 4684c1
timespec_sign (struct timespec a)
Packit Service 4684c1
{
Packit Service 4684c1
  return a.tv_sec < 0 ? -1 : a.tv_sec || a.tv_nsec;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
struct timespec timespec_add (struct timespec, struct timespec)
Packit Service 4684c1
  _GL_ATTRIBUTE_CONST;
Packit Service 4684c1
struct timespec timespec_sub (struct timespec, struct timespec)
Packit Service 4684c1
  _GL_ATTRIBUTE_CONST;
Packit Service 4684c1
struct timespec dtotimespec (double)
Packit Service 4684c1
  _GL_ATTRIBUTE_CONST;
Packit Service 4684c1
Packit Service 4684c1
/* Return an approximation to A, of type 'double'.  */
Packit Service 4684c1
_GL_TIMESPEC_INLINE double
Packit Service 4684c1
timespectod (struct timespec a)
Packit Service 4684c1
{
Packit Service 4684c1
  return a.tv_sec + a.tv_nsec / 1e9;
Packit Service 4684c1
}
Packit Service 4684c1
Packit Service 4684c1
struct timespec current_timespec (void);
Packit Service 4684c1
void gettime (struct timespec *) _GL_ARG_NONNULL ((1));
Packit Service 4684c1
int settime (struct timespec const *) _GL_ARG_NONNULL ((1));
Packit Service 4684c1
Packit Service 4684c1
#ifdef __cplusplus
Packit Service 4684c1
}
Packit Service 4684c1
#endif
Packit Service 4684c1
Packit Service 4684c1
_GL_INLINE_HEADER_END
Packit Service 4684c1
Packit Service 4684c1
#endif