1 /* $NetBSD: time.h,v 1.83 2026/03/15 12:02:08 yamt 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 */ 44 struct 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 /* 53 * TIMEVAL_TO_TIMESPEC: exact conversion 54 * TIMESPEC_TO_TIMEVAL: round down sub us 55 */ 56 #define TIMEVAL_TO_TIMESPEC(tv, ts) do { \ 57 (ts)->tv_sec = (tv)->tv_sec; \ 58 (ts)->tv_nsec = (tv)->tv_usec * 1000; \ 59 } while (0) 60 #define TIMESPEC_TO_TIMEVAL(tv, ts) do { \ 61 (tv)->tv_sec = (ts)->tv_sec; \ 62 (tv)->tv_usec = (suseconds_t)(ts)->tv_nsec / 1000; \ 63 } while (0) 64 65 /* 66 * Note: timezone is obsolete. All timezone handling is now in 67 * userland. Its just here for back compatibility. 68 */ 69 struct timezone { 70 int tz_minuteswest; /* minutes west of Greenwich */ 71 int tz_dsttime; /* type of dst correction */ 72 }; 73 74 /* Operations on timevals. */ 75 #define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0L 76 #define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) 77 #define timercmp(tvp, uvp, cmp) \ 78 (((tvp)->tv_sec == (uvp)->tv_sec) ? \ 79 ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ 80 ((tvp)->tv_sec cmp (uvp)->tv_sec)) 81 #define timeradd(tvp, uvp, vvp) \ 82 do { \ 83 (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ 84 (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \ 85 if ((vvp)->tv_usec >= 1000000) { \ 86 (vvp)->tv_sec++; \ 87 (vvp)->tv_usec -= 1000000; \ 88 } \ 89 } while (0) 90 #define timersub(tvp, uvp, vvp) \ 91 do { \ 92 (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ 93 (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ 94 if ((vvp)->tv_usec < 0) { \ 95 (vvp)->tv_sec--; \ 96 (vvp)->tv_usec += 1000000; \ 97 } \ 98 } while (0) 99 100 /* 101 * hide bintime for _STANDALONE because this header is used for hpcboot.exe, 102 * which is built with compilers which don't recognize LL suffix. 103 * http://mail-index.NetBSD.org/tech-userlevel/2008/02/27/msg000181.html 104 */ 105 #if !defined(_STANDALONE) 106 struct bintime { 107 time_t sec; 108 uint64_t frac; 109 }; 110 111 static __inline void 112 bintime_addx(struct bintime *bt, uint64_t x) 113 { 114 uint64_t u; 115 116 u = bt->frac; 117 bt->frac += x; 118 if (u > bt->frac) 119 bt->sec++; 120 } 121 122 static __inline void 123 bintime_add(struct bintime *bt, const struct bintime *bt2) 124 { 125 uint64_t u; 126 127 u = bt->frac; 128 bt->frac += bt2->frac; 129 if (u > bt->frac) 130 bt->sec++; 131 bt->sec += bt2->sec; 132 } 133 134 static __inline void 135 bintime_sub(struct bintime *bt, const struct bintime *bt2) 136 { 137 uint64_t u; 138 139 u = bt->frac; 140 bt->frac -= bt2->frac; 141 if (u < bt->frac) 142 bt->sec--; 143 bt->sec -= bt2->sec; 144 } 145 146 #define bintimecmp(bta, btb, cmp) \ 147 (((bta)->sec == (btb)->sec) ? \ 148 ((bta)->frac cmp (btb)->frac) : \ 149 ((bta)->sec cmp (btb)->sec)) 150 151 /*- 152 * Background information: 153 * 154 * When converting between timestamps on parallel timescales of differing 155 * resolutions it is historical and scientific practice to round down rather 156 * than doing 4/5 rounding. 157 * 158 * The date changes at midnight, not at noon. 159 * 160 * Even at 15:59:59.999999999 it's not four'o'clock. 161 * 162 * time_second ticks after N.999999999 not after N.4999999999 163 */ 164 165 /* 166 * The magic numbers for converting ms/us/ns to fractions 167 */ 168 169 /* 1ms = (2^64) / 1000 */ 170 #define BINTIME_SCALE_MS ((uint64_t)18446744073709551ULL) 171 172 /* 1us = (2^64) / 1000000 */ 173 #define BINTIME_SCALE_US ((uint64_t)18446744073709ULL) 174 175 /* 1ns = (2^64) / 1000000000 */ 176 #define BINTIME_SCALE_NS ((uint64_t)18446744073ULL) 177 178 static __inline void 179 bintime2timespec(const struct bintime *bt, struct timespec *ts) 180 { 181 182 ts->tv_sec = bt->sec; 183 ts->tv_nsec = 184 (long)((1000000000ULL * (uint32_t)(bt->frac >> 32)) >> 32); 185 } 186 187 static __inline void 188 timespec2bintime(const struct timespec *ts, struct bintime *bt) 189 { 190 191 bt->sec = ts->tv_sec; 192 bt->frac = (uint64_t)ts->tv_nsec * BINTIME_SCALE_NS; 193 } 194 195 static __inline void 196 bintime2timeval(const struct bintime *bt, struct timeval *tv) 197 { 198 199 tv->tv_sec = bt->sec; 200 tv->tv_usec = 201 (suseconds_t)((1000000ULL * (uint32_t)(bt->frac >> 32)) >> 32); 202 } 203 204 static __inline void 205 timeval2bintime(const struct timeval *tv, struct bintime *bt) 206 { 207 208 bt->sec = tv->tv_sec; 209 bt->frac = (uint64_t)tv->tv_usec * BINTIME_SCALE_US; 210 } 211 212 static __inline struct bintime 213 ms2bintime(uint64_t ms) 214 { 215 struct bintime bt; 216 217 bt.sec = (time_t)(ms / 1000U); 218 bt.frac = (uint64_t)(ms % 1000U) * BINTIME_SCALE_MS; 219 220 return bt; 221 } 222 223 static __inline struct bintime 224 us2bintime(uint64_t us) 225 { 226 struct bintime bt; 227 228 bt.sec = (time_t)(us / 1000000U); 229 bt.frac = (uint64_t)(us % 1000000U) * BINTIME_SCALE_US; 230 231 return bt; 232 } 233 234 static __inline struct bintime 235 ns2bintime(uint64_t ns) 236 { 237 struct bintime bt; 238 239 bt.sec = (time_t)(ns / 1000000000U); 240 bt.frac = (uint64_t)(ns % 1000000000U) * BINTIME_SCALE_NS; 241 242 return bt; 243 } 244 #endif /* !defined(_STANDALONE) */ 245 246 /* Operations on timespecs. */ 247 #define timespecclear(tsp) (tsp)->tv_sec = (time_t)((tsp)->tv_nsec = 0L) 248 #define timespecisset(tsp) ((tsp)->tv_sec || (tsp)->tv_nsec) 249 #define timespeccmp(tsp, usp, cmp) \ 250 (((tsp)->tv_sec == (usp)->tv_sec) ? \ 251 ((tsp)->tv_nsec cmp (usp)->tv_nsec) : \ 252 ((tsp)->tv_sec cmp (usp)->tv_sec)) 253 #define timespecadd(tsp, usp, vsp) \ 254 do { \ 255 (vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \ 256 (vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \ 257 if ((vsp)->tv_nsec >= 1000000000L) { \ 258 (vsp)->tv_sec++; \ 259 (vsp)->tv_nsec -= 1000000000L; \ 260 } \ 261 } while (0) 262 #define timespecsub(tsp, usp, vsp) \ 263 do { \ 264 (vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \ 265 (vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \ 266 if ((vsp)->tv_nsec < 0) { \ 267 (vsp)->tv_sec--; \ 268 (vsp)->tv_nsec += 1000000000L; \ 269 } \ 270 } while (0) 271 #define timespec2ns(x) (((uint64_t)(x)->tv_sec) * 1000000000L + (x)->tv_nsec) 272 273 #if defined(_KERNEL) || defined(_TIME_TESTING) 274 #include <sys/stdbool.h> 275 bool timespecaddok(const struct timespec *, const struct timespec *) __pure; 276 bool timespecsubok(const struct timespec *, const struct timespec *) __pure; 277 #endif 278 279 #endif /* _NETBSD_SOURCE */ 280 281 /* 282 * Names of the interval timers, and structure 283 * defining a timer setting. 284 * NB: Must match the CLOCK_ constants below. 285 */ 286 #define ITIMER_REAL 0 287 #define ITIMER_VIRTUAL 1 288 #define ITIMER_PROF 2 289 #define ITIMER_MONOTONIC 3 290 291 struct itimerval { 292 struct timeval it_interval; /* timer interval */ 293 struct timeval it_value; /* current value */ 294 }; 295 296 /* 297 * Structure defined by POSIX.1b to be like a itimerval, but with 298 * timespecs. Used in the timer_*() system calls. 299 */ 300 struct itimerspec { 301 struct timespec it_interval; 302 struct timespec it_value; 303 }; 304 305 #define CLOCK_REALTIME 0 306 #define CLOCK_VIRTUAL 1 307 #define CLOCK_PROF 2 308 #define CLOCK_MONOTONIC 3 309 #define CLOCK_THREAD_CPUTIME_ID 0x20000000 310 #define CLOCK_PROCESS_CPUTIME_ID 0x40000000 311 312 #if defined(_NETBSD_SOURCE) 313 #define TIMER_RELTIME 0x0 /* relative timer */ 314 #endif 315 #define TIMER_ABSTIME 0x1 /* absolute timer */ 316 317 #ifdef _KERNEL 318 #include <sys/timearith.h> 319 #include <sys/timevar.h> 320 #else /* !_KERNEL */ 321 #ifndef _STANDALONE 322 #if (_POSIX_C_SOURCE - 0) >= 200112L || \ 323 (defined(_XOPEN_SOURCE) && defined(_XOPEN_SOURCE_EXTENDED)) || \ 324 (_XOPEN_SOURCE - 0) >= 500 || defined(_NETBSD_SOURCE) 325 #include <sys/select.h> 326 #endif 327 328 #include <sys/cdefs.h> 329 #include <time.h> 330 331 __BEGIN_DECLS 332 #ifndef __LIBC12_SOURCE__ 333 #if (_POSIX_C_SOURCE - 0) >= 200112L || \ 334 defined(_XOPEN_SOURCE) || defined(_NETBSD_SOURCE) 335 int getitimer(int, struct itimerval *) __RENAME(__getitimer50); 336 int gettimeofday(struct timeval * __restrict, void *__restrict) 337 __RENAME(__gettimeofday50); 338 int setitimer(int, const struct itimerval * __restrict, 339 struct itimerval * __restrict) __RENAME(__setitimer50); 340 int utimes(const char *, const struct timeval [2]) __RENAME(__utimes50); 341 #endif /* _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE || _NETBSD_SOURCE */ 342 343 #if defined(_NETBSD_SOURCE) || defined(HAVE_NBTOOL_CONFIG_H) 344 int adjtime(const struct timeval *, struct timeval *) __RENAME(__adjtime50); 345 int futimes(int, const struct timeval [2]) __RENAME(__futimes50); 346 int lutimes(const char *, const struct timeval [2]) __RENAME(__lutimes50); 347 int settimeofday(const struct timeval * __restrict, 348 const void *__restrict) __RENAME(__settimeofday50); 349 #endif /* _NETBSD_SOURCE */ 350 #endif /* __LIBC12_SOURCE__ */ 351 __END_DECLS 352 353 #endif /* !_STANDALONE */ 354 #endif /* !_KERNEL */ 355 #endif /* !_SYS_TIME_H_ */ 356