Blame lib/timespec.h

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