Blame lib/timespec.h

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