1 /* $NetBSD: evutil_time.c,v 1.7 2024/08/18 20:47:21 christos Exp $ */ 2 3 /* 4 * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "event2/event-config.h" 30 #include "evconfig-private.h" 31 32 #ifdef _WIN32 33 #include <winsock2.h> 34 #define WIN32_LEAN_AND_MEAN 35 #include <windows.h> 36 #undef WIN32_LEAN_AND_MEAN 37 #endif 38 39 #include <sys/types.h> 40 #ifdef EVENT__HAVE_STDLIB_H 41 #include <stdlib.h> 42 #endif 43 #include <errno.h> 44 #include <limits.h> 45 #ifndef EVENT__HAVE_GETTIMEOFDAY 46 #include <sys/timeb.h> 47 #endif 48 #if !defined(EVENT__HAVE_NANOSLEEP) && !defined(EVENT__HAVE_USLEEP) && \ 49 !defined(_WIN32) 50 #include <sys/select.h> 51 #endif 52 #include <time.h> 53 #include <sys/stat.h> 54 #include <string.h> 55 56 /** evutil_usleep_() */ 57 #if defined(_WIN32) 58 #elif defined(EVENT__HAVE_NANOSLEEP) 59 #elif defined(EVENT__HAVE_USLEEP) 60 #include <unistd.h> 61 #endif 62 63 #include "event2/util.h" 64 #include "util-internal.h" 65 #include "log-internal.h" 66 #include "mm-internal.h" 67 68 #ifndef EVENT__HAVE_GETTIMEOFDAY 69 /* No gettimeofday; this must be windows. */ 70 71 typedef void (WINAPI *GetSystemTimePreciseAsFileTime_fn_t) (LPFILETIME); 72 73 int 74 evutil_gettimeofday(struct timeval *tv, struct timezone *tz) 75 { 76 #ifdef _MSC_VER 77 #define U64_LITERAL(n) n##ui64 78 #else 79 #define U64_LITERAL(n) n##llu 80 #endif 81 82 /* Conversion logic taken from Tor, which in turn took it 83 * from Perl. GetSystemTimeAsFileTime returns its value as 84 * an unaligned (!) 64-bit value containing the number of 85 * 100-nanosecond intervals since 1 January 1601 UTC. */ 86 #define EPOCH_BIAS U64_LITERAL(116444736000000000) 87 #define UNITS_PER_SEC U64_LITERAL(10000000) 88 #define USEC_PER_SEC U64_LITERAL(1000000) 89 #define UNITS_PER_USEC U64_LITERAL(10) 90 union { 91 FILETIME ft_ft; 92 ev_uint64_t ft_64; 93 } ft; 94 95 if (tv == NULL) 96 return -1; 97 98 static GetSystemTimePreciseAsFileTime_fn_t GetSystemTimePreciseAsFileTime_fn = NULL; 99 static int check_precise = 1; 100 101 if (EVUTIL_UNLIKELY(check_precise)) { 102 HMODULE h = evutil_load_windows_system_library_(TEXT("kernel32.dll")); 103 if (h != NULL) 104 GetSystemTimePreciseAsFileTime_fn = 105 (GetSystemTimePreciseAsFileTime_fn_t) 106 GetProcAddress(h, "GetSystemTimePreciseAsFileTime"); 107 check_precise = 0; 108 } 109 110 if (GetSystemTimePreciseAsFileTime_fn != NULL) 111 GetSystemTimePreciseAsFileTime_fn(&ft.ft_ft); 112 else 113 GetSystemTimeAsFileTime(&ft.ft_ft); 114 115 if (EVUTIL_UNLIKELY(ft.ft_64 < EPOCH_BIAS)) { 116 /* Time before the unix epoch. */ 117 return -1; 118 } 119 ft.ft_64 -= EPOCH_BIAS; 120 tv->tv_sec = (long) (ft.ft_64 / UNITS_PER_SEC); 121 tv->tv_usec = (long) ((ft.ft_64 / UNITS_PER_USEC) % USEC_PER_SEC); 122 return 0; 123 } 124 #endif 125 126 #define MAX_SECONDS_IN_MSEC_LONG \ 127 (((LONG_MAX) - 999) / 1000) 128 129 long 130 evutil_tv_to_msec_(const struct timeval *tv) 131 { 132 if (tv->tv_usec > 1000000 || tv->tv_sec > MAX_SECONDS_IN_MSEC_LONG) 133 return -1; 134 135 return (tv->tv_sec * 1000) + ((tv->tv_usec + 999) / 1000); 136 } 137 138 /* 139 Replacement for usleep on platforms that don't have one. Not guaranteed to 140 be any more finegrained than 1 msec. 141 */ 142 void 143 evutil_usleep_(const struct timeval *tv) 144 { 145 if (!tv) 146 return; 147 #if defined(_WIN32) 148 { 149 __int64 usec; 150 LARGE_INTEGER li; 151 HANDLE timer; 152 153 usec = tv->tv_sec * 1000000LL + tv->tv_usec; 154 if (!usec) 155 return; 156 157 li.QuadPart = -10LL * usec; 158 timer = CreateWaitableTimer(NULL, TRUE, NULL); 159 if (!timer) 160 return; 161 162 SetWaitableTimer(timer, &li, 0, NULL, NULL, 0); 163 WaitForSingleObject(timer, INFINITE); 164 CloseHandle(timer); 165 } 166 #elif defined(EVENT__HAVE_NANOSLEEP) 167 { 168 struct timespec ts; 169 ts.tv_sec = tv->tv_sec; 170 ts.tv_nsec = tv->tv_usec*1000; 171 nanosleep(&ts, NULL); 172 } 173 #elif defined(EVENT__HAVE_USLEEP) 174 /* Some systems don't like to usleep more than 999999 usec */ 175 sleep(tv->tv_sec); 176 usleep(tv->tv_usec); 177 #else 178 { 179 struct timeval tv2 = *tv; 180 select(0, NULL, NULL, NULL, &tv2); 181 } 182 #endif 183 } 184 185 int 186 evutil_date_rfc1123(char *date, const size_t datelen, const struct tm *tm) 187 { 188 static const char *DAYS[] = 189 { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; 190 static const char *MONTHS[] = 191 { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; 192 193 time_t t = time(NULL); 194 195 #if defined(EVENT__HAVE__GMTIME64_S) || !defined(_WIN32) 196 struct tm sys; 197 #endif 198 199 /* If `tm` is null, set system's current time. */ 200 if (tm == NULL) { 201 #if !defined(_WIN32) 202 gmtime_r(&t, &sys); 203 tm = &sys; 204 /** detect _gmtime64()/_gmtime64_s() */ 205 #elif defined(EVENT__HAVE__GMTIME64_S) 206 errno_t err; 207 err = _gmtime64_s(&sys, &t); 208 if (err) { 209 event_errx(1, "Invalid argument to _gmtime64_s"); 210 } else { 211 tm = &sys; 212 } 213 #elif defined(EVENT__HAVE__GMTIME64) 214 tm = _gmtime64(&t); 215 #else 216 tm = gmtime(&t); 217 #endif 218 } 219 220 return evutil_snprintf( 221 date, datelen, "%s, %02d %s %4d %02d:%02d:%02d GMT", 222 DAYS[tm->tm_wday], tm->tm_mday, MONTHS[tm->tm_mon], 223 1900 + tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec); 224 } 225 226 /* 227 This function assumes it's called repeatedly with a 228 not-actually-so-monotonic time source whose outputs are in 'tv'. It 229 implements a trivial ratcheting mechanism so that the values never go 230 backwards. 231 */ 232 static void 233 adjust_monotonic_time(struct evutil_monotonic_timer *base, 234 struct timeval *tv) 235 { 236 evutil_timeradd(tv, &base->adjust_monotonic_clock, tv); 237 238 if (evutil_timercmp(tv, &base->last_time, <)) { 239 /* Guess it wasn't monotonic after all. */ 240 struct timeval adjust; 241 evutil_timersub(&base->last_time, tv, &adjust); 242 evutil_timeradd(&adjust, &base->adjust_monotonic_clock, 243 &base->adjust_monotonic_clock); 244 *tv = base->last_time; 245 } 246 base->last_time = *tv; 247 } 248 249 /* 250 Allocate a new struct evutil_monotonic_timer 251 */ 252 struct evutil_monotonic_timer * 253 evutil_monotonic_timer_new(void) 254 { 255 struct evutil_monotonic_timer *p = NULL; 256 257 p = mm_malloc(sizeof(*p)); 258 if (!p) goto done; 259 260 memset(p, 0, sizeof(*p)); 261 262 done: 263 return p; 264 } 265 266 /* 267 Free a struct evutil_monotonic_timer 268 */ 269 void 270 evutil_monotonic_timer_free(struct evutil_monotonic_timer *timer) 271 { 272 if (timer) { 273 mm_free(timer); 274 } 275 } 276 277 /* 278 Set up a struct evutil_monotonic_timer for initial use 279 */ 280 int 281 evutil_configure_monotonic_time(struct evutil_monotonic_timer *timer, 282 int flags) 283 { 284 return evutil_configure_monotonic_time_(timer, flags); 285 } 286 287 /* 288 Query the current monotonic time 289 */ 290 int 291 evutil_gettime_monotonic(struct evutil_monotonic_timer *timer, 292 struct timeval *tp) 293 { 294 return evutil_gettime_monotonic_(timer, tp); 295 } 296 297 298 #if defined(HAVE_POSIX_MONOTONIC) 299 /* ===== 300 The POSIX clock_gettime() interface provides a few ways to get at a 301 monotonic clock. CLOCK_MONOTONIC is most widely supported. Linux also 302 provides a CLOCK_MONOTONIC_COARSE with accuracy of about 1-4 msec. 303 304 On all platforms I'm aware of, CLOCK_MONOTONIC really is monotonic. 305 Platforms don't agree about whether it should jump on a sleep/resume. 306 */ 307 308 int 309 evutil_configure_monotonic_time_(struct evutil_monotonic_timer *base, 310 int flags) 311 { 312 /* CLOCK_MONOTONIC exists on FreeBSD, Linux, and Solaris. You need to 313 * check for it at runtime, because some older kernel versions won't 314 * have it working. */ 315 #ifdef CLOCK_MONOTONIC_COARSE 316 const int precise = flags & EV_MONOT_PRECISE; 317 #endif 318 const int fallback = flags & EV_MONOT_FALLBACK; 319 struct timespec ts; 320 321 #ifdef CLOCK_MONOTONIC_COARSE 322 if (CLOCK_MONOTONIC_COARSE < 0) { 323 /* Technically speaking, nothing keeps CLOCK_* from being 324 * negative (as far as I know). This check and the one below 325 * make sure that it's safe for us to use -1 as an "unset" 326 * value. */ 327 event_errx(1,"I didn't expect CLOCK_MONOTONIC_COARSE to be < 0"); 328 } 329 if (! precise && ! fallback) { 330 if (clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) == 0) { 331 base->monotonic_clock = CLOCK_MONOTONIC_COARSE; 332 return 0; 333 } 334 } 335 #endif 336 if (!fallback && clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { 337 base->monotonic_clock = CLOCK_MONOTONIC; 338 return 0; 339 } 340 341 if (CLOCK_MONOTONIC < 0) { 342 event_errx(1,"I didn't expect CLOCK_MONOTONIC to be < 0"); 343 } 344 345 base->monotonic_clock = -1; 346 return 0; 347 } 348 349 int 350 evutil_gettime_monotonic_(struct evutil_monotonic_timer *base, 351 struct timeval *tp) 352 { 353 struct timespec ts; 354 355 if (base->monotonic_clock < 0) { 356 if (evutil_gettimeofday(tp, NULL) < 0) 357 return -1; 358 adjust_monotonic_time(base, tp); 359 return 0; 360 } 361 362 if (clock_gettime(base->monotonic_clock, &ts) == -1) 363 return -1; 364 tp->tv_sec = ts.tv_sec; 365 tp->tv_usec = ts.tv_nsec / 1000; 366 367 return 0; 368 } 369 #endif 370 371 #if defined(HAVE_MACH_MONOTONIC) 372 /* ====== 373 Apple is a little late to the POSIX party. And why not? Instead of 374 clock_gettime(), they provide mach_absolute_time(). Its units are not 375 fixed; we need to use mach_timebase_info() to get the right functions to 376 convert its units into nanoseconds. 377 378 To all appearances, mach_absolute_time() seems to be honest-to-goodness 379 monotonic. Whether it stops during sleep or not is unspecified in 380 principle, and dependent on CPU architecture in practice. 381 */ 382 383 int 384 evutil_configure_monotonic_time_(struct evutil_monotonic_timer *base, 385 int flags) 386 { 387 const int fallback = flags & EV_MONOT_FALLBACK; 388 struct mach_timebase_info mi; 389 memset(base, 0, sizeof(*base)); 390 /* OSX has mach_absolute_time() */ 391 if (!fallback && 392 mach_timebase_info(&mi) == 0 && 393 mach_absolute_time() != 0) { 394 /* mach_timebase_info tells us how to convert 395 * mach_absolute_time() into nanoseconds, but we 396 * want to use microseconds instead. */ 397 mi.denom *= 1000; 398 memcpy(&base->mach_timebase_units, &mi, sizeof(mi)); 399 } else { 400 base->mach_timebase_units.numer = 0; 401 } 402 return 0; 403 } 404 405 int 406 evutil_gettime_monotonic_(struct evutil_monotonic_timer *base, 407 struct timeval *tp) 408 { 409 ev_uint64_t abstime, usec; 410 if (base->mach_timebase_units.numer == 0) { 411 if (evutil_gettimeofday(tp, NULL) < 0) 412 return -1; 413 adjust_monotonic_time(base, tp); 414 return 0; 415 } 416 417 abstime = mach_absolute_time(); 418 usec = (abstime * base->mach_timebase_units.numer) 419 / (base->mach_timebase_units.denom); 420 tp->tv_sec = usec / 1000000; 421 tp->tv_usec = usec % 1000000; 422 423 return 0; 424 } 425 #endif 426 427 #if defined(HAVE_WIN32_MONOTONIC) 428 /* ===== 429 Turn we now to Windows. Want monontonic time on Windows? 430 431 Windows has QueryPerformanceCounter(), which gives time most high- 432 resolution time. It's a pity it's not so monotonic in practice; it's 433 also got some fun bugs, especially: with older Windowses, under 434 virtualizations, with funny hardware, on multiprocessor systems, and so 435 on. PEP418 [1] has a nice roundup of the issues here. 436 437 There's GetTickCount64() on Vista and later, which gives a number of 1-msec 438 ticks since startup. The accuracy here might be as bad as 10-20 msec, I 439 hear. There's an undocumented function (NtSetTimerResolution) that 440 allegedly increases the accuracy. Good luck! 441 442 There's also GetTickCount(), which is only 32 bits, but seems to be 443 supported on pre-Vista versions of Windows. Apparently, you can coax 444 another 14 bits out of it, giving you 2231 years before rollover. 445 446 The less said about timeGetTime() the better. 447 448 "We don't care. We don't have to. We're the Phone Company." 449 -- Lily Tomlin, SNL 450 451 Our strategy, if precise timers are turned off, is to just use the best 452 GetTickCount equivalent available. If we've been asked for precise timing, 453 then we mostly[2] assume that GetTickCount is monotonic, and correct 454 GetPerformanceCounter to approximate it. 455 456 [1] http://www.python.org/dev/peps/pep-0418 457 [2] Of course, we feed the Windows stuff into adjust_monotonic_time() 458 anyway, just in case it isn't. 459 460 */ 461 /* 462 Parts of our logic in the win32 timer code here are closely based on 463 BitTorrent's libUTP library. That code is subject to the following 464 license: 465 466 Copyright (c) 2010 BitTorrent, Inc. 467 468 Permission is hereby granted, free of charge, to any person obtaining a 469 copy of this software and associated documentation files (the 470 "Software"), to deal in the Software without restriction, including 471 without limitation the rights to use, copy, modify, merge, publish, 472 distribute, sublicense, and/or sell copies of the Software, and to 473 permit persons to whom the Software is furnished to do so, subject to 474 the following conditions: 475 476 The above copyright notice and this permission notice shall be included 477 in all copies or substantial portions of the Software. 478 479 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 480 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 481 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 482 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 483 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 484 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 485 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 486 */ 487 488 static ev_uint64_t 489 evutil_GetTickCount_(struct evutil_monotonic_timer *base) 490 { 491 if (base->GetTickCount64_fn) { 492 /* Let's just use GetTickCount64 if we can. */ 493 return base->GetTickCount64_fn(); 494 } else if (base->GetTickCount_fn) { 495 /* Greg Hazel assures me that this works, that BitTorrent has 496 * done it for years, and this it won't turn around and 497 * bite us. He says they found it on some game programmers' 498 * forum some time around 2007. 499 */ 500 ev_uint64_t v = base->GetTickCount_fn(); 501 return (DWORD)v | ((v >> 18) & 0xFFFFFFFF00000000); 502 } else { 503 /* Here's the fallback implementation. We have to use 504 * GetTickCount() with its given signature, so we only get 505 * 32 bits worth of milliseconds, which will roll ove every 506 * 49 days or so. */ 507 DWORD ticks = GetTickCount(); 508 if (ticks < base->last_tick_count) { 509 base->adjust_tick_count += ((ev_uint64_t)1) << 32; 510 } 511 base->last_tick_count = ticks; 512 return ticks + base->adjust_tick_count; 513 } 514 } 515 516 int 517 evutil_configure_monotonic_time_(struct evutil_monotonic_timer *base, 518 int flags) 519 { 520 const int precise = flags & EV_MONOT_PRECISE; 521 const int fallback = flags & EV_MONOT_FALLBACK; 522 HANDLE h; 523 memset(base, 0, sizeof(*base)); 524 525 h = evutil_load_windows_system_library_(TEXT("kernel32.dll")); 526 if (h != NULL && !fallback) { 527 base->GetTickCount64_fn = (ev_GetTickCount_func)GetProcAddress(h, "GetTickCount64"); 528 base->GetTickCount_fn = (ev_GetTickCount_func)GetProcAddress(h, "GetTickCount"); 529 } 530 531 base->first_tick = base->last_tick_count = evutil_GetTickCount_(base); 532 if (precise && !fallback) { 533 LARGE_INTEGER freq; 534 if (QueryPerformanceFrequency(&freq)) { 535 LARGE_INTEGER counter; 536 QueryPerformanceCounter(&counter); 537 base->first_counter = counter.QuadPart; 538 base->usec_per_count = 1.0e6 / freq.QuadPart; 539 base->use_performance_counter = 1; 540 } 541 } 542 543 return 0; 544 } 545 546 static inline ev_int64_t 547 abs64(ev_int64_t i) 548 { 549 return i < 0 ? -i : i; 550 } 551 552 553 int 554 evutil_gettime_monotonic_(struct evutil_monotonic_timer *base, 555 struct timeval *tp) 556 { 557 ev_uint64_t ticks = evutil_GetTickCount_(base); 558 if (base->use_performance_counter) { 559 /* Here's a trick we took from BitTorrent's libutp, at Greg 560 * Hazel's recommendation. We use QueryPerformanceCounter for 561 * our high-resolution timer, but use GetTickCount*() to keep 562 * it sane, and adjust_monotonic_time() to keep it monotonic. 563 */ 564 LARGE_INTEGER counter; 565 ev_int64_t counter_elapsed, counter_usec_elapsed, ticks_elapsed; 566 QueryPerformanceCounter(&counter); 567 counter_elapsed = (ev_int64_t) 568 (counter.QuadPart - base->first_counter); 569 ticks_elapsed = ticks - base->first_tick; 570 /* TODO: This may upset VC6. If you need this to work with 571 * VC6, please supply an appropriate patch. */ 572 counter_usec_elapsed = (ev_int64_t) 573 (counter_elapsed * base->usec_per_count); 574 575 if (abs64(ticks_elapsed*1000 - counter_usec_elapsed) > 1000000) { 576 /* It appears that the QueryPerformanceCounter() 577 * result is more than 1 second away from 578 * GetTickCount() result. Let's adjust it to be as 579 * accurate as we can; adjust_monotnonic_time() below 580 * will keep it monotonic. */ 581 counter_usec_elapsed = ticks_elapsed * 1000; 582 base->first_counter = (ev_uint64_t) (counter.QuadPart - counter_usec_elapsed / base->usec_per_count); 583 } 584 tp->tv_sec = (time_t) (counter_usec_elapsed / 1000000); 585 tp->tv_usec = counter_usec_elapsed % 1000000; 586 587 } else { 588 /* We're just using GetTickCount(). */ 589 tp->tv_sec = (time_t) (ticks / 1000); 590 tp->tv_usec = (ticks % 1000) * 1000; 591 } 592 adjust_monotonic_time(base, tp); 593 594 return 0; 595 } 596 #endif 597 598 #if defined(HAVE_FALLBACK_MONOTONIC) 599 /* ===== 600 And if none of the other options work, let's just use gettimeofday(), and 601 ratchet it forward so that it acts like a monotonic timer, whether it 602 wants to or not. 603 */ 604 605 int 606 evutil_configure_monotonic_time_(struct evutil_monotonic_timer *base, 607 int precise) 608 { 609 memset(base, 0, sizeof(*base)); 610 return 0; 611 } 612 613 int 614 evutil_gettime_monotonic_(struct evutil_monotonic_timer *base, 615 struct timeval *tp) 616 { 617 if (evutil_gettimeofday(tp, NULL) < 0) 618 return -1; 619 adjust_monotonic_time(base, tp); 620 return 0; 621 622 } 623 #endif 624