1/* $NetBSD: time.h,v 1.81 2024/05/12 10:34:56 rillig Exp $ */ 2 3/* 4 * Copyright (c) 1982, 1986, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 * @(#)time.h 8.5 (Berkeley) 5/4/95 32 */ 33 34#ifndef _SYS_TIME_H_ 35#define _SYS_TIME_H_ 36 37#include <sys/featuretest.h> 38#include <sys/types.h> 39 40/* 41 * Structure returned by gettimeofday(2) system call, 42 * and used in other calls. 43 */ 44struct timeval { 45 time_t tv_sec; /* seconds */ 46 suseconds_t tv_usec; /* and microseconds */ 47}; 48 49#include <sys/timespec.h> 50 51#if defined(_NETBSD_SOURCE) 52#define TIMEVAL_TO_TIMESPEC(tv, ts) do { \ 53 (ts)->tv_sec = (tv)->tv_sec; \ 54 (ts)->tv_nsec = (tv)->tv_usec * 1000; \ 55} while (0) 56#define TIMESPEC_TO_TIMEVAL(tv, ts) do { \ 57 (tv)->tv_sec = (ts)->tv_sec; \ 58 (tv)->tv_usec = (suseconds_t)(ts)->tv_nsec / 1000; \ 59} while (0) 60 61/* 62 * Note: timezone is obsolete. All timezone handling is now in 63 * userland. Its just here for back compatibility. 64 */ 65struct timezone { 66 int tz_minuteswest; /* minutes west of Greenwich */ 67 int tz_dsttime; /* type of dst correction */ 68}; 69 70/* Operations on timevals. */ 71#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0L 72#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) 73#define timercmp(tvp, uvp, cmp) \ 74 (((tvp)->tv_sec == (uvp)->tv_sec) ? \ 75 ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ 76 ((tvp)->tv_sec cmp (uvp)->tv_sec)) 77#define timeradd(tvp, uvp, vvp) \ 78 do { \ 79 (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ 80 (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \ 81 if ((vvp)->tv_usec >= 1000000) { \ 82 (vvp)->tv_sec++; \ 83 (vvp)->tv_usec -= 1000000; \ 84 } \ 85 } while (0) 86#define timersub(tvp, uvp, vvp) \ 87 do { \ 88 (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ 89 (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ 90 if ((vvp)->tv_usec < 0) { \ 91 (vvp)->tv_sec--; \ 92 (vvp)->tv_usec += 1000000; \ 93 } \ 94 } while (0) 95 96/* 97 * hide bintime for _STANDALONE because this header is used for hpcboot.exe, 98 * which is built with compilers which don't recognize LL suffix. 99 * http://mail-index.NetBSD.org/tech-userlevel/2008/02/27/msg000181.html 100 */ 101#if !defined(_STANDALONE) 102struct bintime { 103 time_t sec; 104 uint64_t frac; 105}; 106 107static __inline void 108bintime_addx(struct bintime *bt, uint64_t x) 109{ 110 uint64_t u; 111 112 u = bt->frac; 113 bt->frac += x; 114 if (u > bt->frac) 115 bt->sec++; 116} 117 118static __inline void 119bintime_add(struct bintime *bt, const struct bintime *bt2) 120{ 121 uint64_t u; 122 123 u = bt->frac; 124 bt->frac += bt2->frac; 125 if (u > bt->frac) 126 bt->sec++; 127 bt->sec += bt2->sec; 128} 129 130static __inline void 131bintime_sub(struct bintime *bt, const struct bintime *bt2) 132{ 133 uint64_t u; 134 135 u = bt->frac; 136 bt->frac -= bt2->frac; 137 if (u < bt->frac) 138 bt->sec--; 139 bt->sec -= bt2->sec; 140} 141 142#define bintimecmp(bta, btb, cmp) \ 143 (((bta)->sec == (btb)->sec) ? \ 144 ((bta)->frac cmp (btb)->frac) : \ 145 ((bta)->sec cmp (btb)->sec)) 146 147/*- 148 * Background information: 149 * 150 * When converting between timestamps on parallel timescales of differing 151 * resolutions it is historical and scientific practice to round down rather 152 * than doing 4/5 rounding. 153 * 154 * The date changes at midnight, not at noon. 155 * 156 * Even at 15:59:59.999999999 it's not four'o'clock. 157 * 158 * time_second ticks after N.999999999 not after N.4999999999 159 */ 160 161/* 162 * The magic numbers for converting ms/us/ns to fractions 163 */ 164 165/* 1ms = (2^64) / 1000 */ 166#define BINTIME_SCALE_MS ((uint64_t)18446744073709551ULL) 167 168/* 1us = (2^64) / 1000000 */ 169#define BINTIME_SCALE_US ((uint64_t)18446744073709ULL) 170 171/* 1ns = (2^64) / 1000000000 */ 172#define BINTIME_SCALE_NS ((uint64_t)18446744073ULL) 173 174static __inline void 175bintime2timespec(const struct bintime *bt, struct timespec *ts) 176{ 177 178 ts->tv_sec = bt->sec; 179 ts->tv_nsec = 180 (long)((1000000000ULL * (uint32_t)(bt->frac >> 32)) >> 32); 181} 182 183static __inline void 184timespec2bintime(const struct timespec *ts, struct bintime *bt) 185{ 186 187 bt->sec = ts->tv_sec; 188 bt->frac = (uint64_t)ts->tv_nsec * BINTIME_SCALE_NS; 189} 190 191static __inline void 192bintime2timeval(const struct bintime *bt, struct timeval *tv) 193{ 194 195 tv->tv_sec = bt->sec; 196 tv->tv_usec = 197 (suseconds_t)((1000000ULL * (uint32_t)(bt->frac >> 32)) >> 32); 198} 199 200static __inline void 201timeval2bintime(const struct timeval *tv, struct bintime *bt) 202{ 203 204 bt->sec = tv->tv_sec; 205 bt->frac = (uint64_t)tv->tv_usec * BINTIME_SCALE_US; 206} 207 208static __inline struct bintime 209ms2bintime(uint64_t ms) 210{ 211 struct bintime bt; 212 213 bt.sec = (time_t)(ms / 1000U); 214 bt.frac = (uint64_t)(ms % 1000U) * BINTIME_SCALE_MS; 215 216 return bt; 217} 218 219static __inline struct bintime 220us2bintime(uint64_t us) 221{ 222 struct bintime bt; 223 224 bt.sec = (time_t)(us / 1000000U); 225 bt.frac = (uint64_t)(us % 1000000U) * BINTIME_SCALE_US; 226 227 return bt; 228} 229 230static __inline struct bintime 231ns2bintime(uint64_t ns) 232{ 233 struct bintime bt; 234 235 bt.sec = (time_t)(ns / 1000000000U); 236 bt.frac = (uint64_t)(ns % 1000000000U) * BINTIME_SCALE_NS; 237 238 return bt; 239} 240#endif /* !defined(_STANDALONE) */ 241 242/* Operations on timespecs. */ 243#define timespecclear(tsp) (tsp)->tv_sec = (time_t)((tsp)->tv_nsec = 0L) 244#define timespecisset(tsp) ((tsp)->tv_sec || (tsp)->tv_nsec) 245#define timespeccmp(tsp, usp, cmp) \ 246 (((tsp)->tv_sec == (usp)->tv_sec) ? \ 247 ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \ 248 ((tsp)->tv_sec cmp (usp)->tv_sec)) 249#define timespecadd(tsp, usp, vsp) \ 250 do { \ 251 (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \ 252 (vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \ 253 if ((vsp)->tv_nsec >= 1000000000L) { \ 254 (vsp)->tv_sec++; \ 255 (vsp)->tv_nsec -= 1000000000L; \ 256 } \ 257 } while (0) 258#define timespecsub(tsp, usp, vsp) \ 259 do { \ 260 (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \ 261 (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \ 262 if ((vsp)->tv_nsec < 0) { \ 263 (vsp)->tv_sec--; \ 264 (vsp)->tv_nsec += 1000000000L; \ 265 } \ 266 } while (0) 267#define timespec2ns(x) (((uint64_t)(x)->tv_sec) * 1000000000L + (x)->tv_nsec) 268 269#ifdef _KERNEL 270bool timespecaddok(const struct timespec *, const struct timespec *) __pure; 271bool timespecsubok(const struct timespec *, const struct timespec *) __pure; 272#endif 273 274#endif /* _NETBSD_SOURCE */ 275 276/* 277 * Names of the interval timers, and structure 278 * defining a timer setting. 279 * NB: Must match the CLOCK_ constants below. 280 */ 281#define ITIMER_REAL 0 282#define ITIMER_VIRTUAL 1 283#define ITIMER_PROF 2 284#define ITIMER_MONOTONIC 3 285 286struct itimerval { 287 struct timeval it_interval; /* timer interval */ 288 struct timeval it_value; /* current value */ 289}; 290 291/* 292 * Structure defined by POSIX.1b to be like a itimerval, but with 293 * timespecs. Used in the timer_*() system calls. 294 */ 295struct itimerspec { 296 struct timespec it_interval; 297 struct timespec it_value; 298}; 299 300#define CLOCK_REALTIME 0 301#define CLOCK_VIRTUAL 1 302#define CLOCK_PROF 2 303#define CLOCK_MONOTONIC 3 304#define CLOCK_THREAD_CPUTIME_ID 0x20000000 305#define CLOCK_PROCESS_CPUTIME_ID 0x40000000 306 307#if defined(_NETBSD_SOURCE) 308#define TIMER_RELTIME 0x0 /* relative timer */ 309#endif 310#define TIMER_ABSTIME 0x1 /* absolute timer */ 311 312#ifdef _KERNEL 313#include <sys/timevar.h> 314#else /* !_KERNEL */ 315#ifndef _STANDALONE 316#if (_POSIX_C_SOURCE - 0) >= 200112L || \ 317 (defined(_XOPEN_SOURCE) && defined(_XOPEN_SOURCE_EXTENDED)) || \ 318 (_XOPEN_SOURCE - 0) >= 500 || defined(_NETBSD_SOURCE) 319#include <sys/select.h> 320#endif 321 322#include <sys/cdefs.h> 323#include <time.h> 324 325__BEGIN_DECLS 326#ifndef __LIBC12_SOURCE__ 327#if (_POSIX_C_SOURCE - 0) >= 200112L || \ 328 defined(_XOPEN_SOURCE) || defined(_NETBSD_SOURCE) 329int getitimer(int, struct itimerval *) __RENAME(__getitimer50); 330int gettimeofday(struct timeval * __restrict, void *__restrict) 331 __RENAME(__gettimeofday50); 332int setitimer(int, const struct itimerval * __restrict, 333 struct itimerval * __restrict) __RENAME(__setitimer50); 334int utimes(const char *, const struct timeval [2]) __RENAME(__utimes50); 335#endif /* _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE || _NETBSD_SOURCE */ 336 337#if defined(_NETBSD_SOURCE) || defined(HAVE_NBTOOL_CONFIG_H) 338int adjtime(const struct timeval *, struct timeval *) __RENAME(__adjtime50); 339int futimes(int, const struct timeval [2]) __RENAME(__futimes50); 340int lutimes(const char *, const struct timeval [2]) __RENAME(__lutimes50); 341int settimeofday(const struct timeval * __restrict, 342 const void *__restrict) __RENAME(__settimeofday50); 343#endif /* _NETBSD_SOURCE */ 344#endif /* __LIBC12_SOURCE__ */ 345__END_DECLS 346 347#endif /* !_STANDALONE */ 348#endif /* !_KERNEL */ 349#endif /* !_SYS_TIME_H_ */ 350