1 /* $NetBSD: time.h,v 1.82 2024/12/22 23:24:20 riastradh 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 #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 */ 65 struct 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) 102 struct bintime { 103 time_t sec; 104 uint64_t frac; 105 }; 106 107 static __inline void 108 bintime_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 118 static __inline void 119 bintime_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 130 static __inline void 131 bintime_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 174 static __inline void 175 bintime2timespec(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 183 static __inline void 184 timespec2bintime(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 191 static __inline void 192 bintime2timeval(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 200 static __inline void 201 timeval2bintime(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 208 static __inline struct bintime 209 ms2bintime(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 219 static __inline struct bintime 220 us2bintime(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 230 static __inline struct bintime 231 ns2bintime(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 #if defined(_KERNEL) || defined(_TIME_TESTING) 270 #include <sys/stdbool.h> 271 bool timespecaddok(const struct timespec *, const struct timespec *) __pure; 272 bool timespecsubok(const struct timespec *, const struct timespec *) __pure; 273 #endif 274 275 #endif /* _NETBSD_SOURCE */ 276 277 /* 278 * Names of the interval timers, and structure 279 * defining a timer setting. 280 * NB: Must match the CLOCK_ constants below. 281 */ 282 #define ITIMER_REAL 0 283 #define ITIMER_VIRTUAL 1 284 #define ITIMER_PROF 2 285 #define ITIMER_MONOTONIC 3 286 287 struct itimerval { 288 struct timeval it_interval; /* timer interval */ 289 struct timeval it_value; /* current value */ 290 }; 291 292 /* 293 * Structure defined by POSIX.1b to be like a itimerval, but with 294 * timespecs. Used in the timer_*() system calls. 295 */ 296 struct itimerspec { 297 struct timespec it_interval; 298 struct timespec it_value; 299 }; 300 301 #define CLOCK_REALTIME 0 302 #define CLOCK_VIRTUAL 1 303 #define CLOCK_PROF 2 304 #define CLOCK_MONOTONIC 3 305 #define CLOCK_THREAD_CPUTIME_ID 0x20000000 306 #define CLOCK_PROCESS_CPUTIME_ID 0x40000000 307 308 #if defined(_NETBSD_SOURCE) 309 #define TIMER_RELTIME 0x0 /* relative timer */ 310 #endif 311 #define TIMER_ABSTIME 0x1 /* absolute timer */ 312 313 #ifdef _KERNEL 314 #include <sys/timearith.h> 315 #include <sys/timevar.h> 316 #else /* !_KERNEL */ 317 #ifndef _STANDALONE 318 #if (_POSIX_C_SOURCE - 0) >= 200112L || \ 319 (defined(_XOPEN_SOURCE) && defined(_XOPEN_SOURCE_EXTENDED)) || \ 320 (_XOPEN_SOURCE - 0) >= 500 || defined(_NETBSD_SOURCE) 321 #include <sys/select.h> 322 #endif 323 324 #include <sys/cdefs.h> 325 #include <time.h> 326 327 __BEGIN_DECLS 328 #ifndef __LIBC12_SOURCE__ 329 #if (_POSIX_C_SOURCE - 0) >= 200112L || \ 330 defined(_XOPEN_SOURCE) || defined(_NETBSD_SOURCE) 331 int getitimer(int, struct itimerval *) __RENAME(__getitimer50); 332 int gettimeofday(struct timeval * __restrict, void *__restrict) 333 __RENAME(__gettimeofday50); 334 int setitimer(int, const struct itimerval * __restrict, 335 struct itimerval * __restrict) __RENAME(__setitimer50); 336 int utimes(const char *, const struct timeval [2]) __RENAME(__utimes50); 337 #endif /* _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE || _NETBSD_SOURCE */ 338 339 #if defined(_NETBSD_SOURCE) || defined(HAVE_NBTOOL_CONFIG_H) 340 int adjtime(const struct timeval *, struct timeval *) __RENAME(__adjtime50); 341 int futimes(int, const struct timeval [2]) __RENAME(__futimes50); 342 int lutimes(const char *, const struct timeval [2]) __RENAME(__lutimes50); 343 int settimeofday(const struct timeval * __restrict, 344 const void *__restrict) __RENAME(__settimeofday50); 345 #endif /* _NETBSD_SOURCE */ 346 #endif /* __LIBC12_SOURCE__ */ 347 __END_DECLS 348 349 #endif /* !_STANDALONE */ 350 #endif /* !_KERNEL */ 351 #endif /* !_SYS_TIME_H_ */ 352