compat_time.c (24538B)
1 /* Copyright (c) 2003-2004, Roger Dingledine 2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 3 * Copyright (c) 2007-2025, The Tor Project, Inc. */ 4 /* See LICENSE for licensing information */ 5 6 /** 7 * \file compat_time.c 8 * \brief Portable wrappers for finding out the current time, running 9 * timers, etc. 10 **/ 11 12 #define COMPAT_TIME_PRIVATE 13 #include "lib/time/compat_time.h" 14 15 #include "lib/err/torerr.h" 16 #include "lib/log/log.h" 17 #include "lib/log/util_bug.h" 18 #include "lib/intmath/muldiv.h" 19 #include "lib/intmath/bits.h" 20 #include "lib/fs/winlib.h" 21 #include "lib/wallclock/timeval.h" 22 23 #ifdef _WIN32 24 #include <winsock2.h> 25 #include <windows.h> 26 #endif 27 28 #ifdef HAVE_SYS_TYPES_H 29 #include <sys/types.h> 30 #endif 31 #ifdef HAVE_SYS_TIME_H 32 #include <sys/time.h> 33 #endif 34 #ifdef HAVE_UNISTD_H 35 #include <unistd.h> 36 #endif 37 #ifdef TOR_UNIT_TESTS 38 #if !defined(HAVE_USLEEP) && defined(HAVE_SYS_SELECT_H) 39 /* as fallback implementation for tor_sleep_msec */ 40 #include <sys/select.h> 41 #endif 42 #endif /* defined(TOR_UNIT_TESTS) */ 43 44 #ifdef __APPLE__ 45 #include <mach/mach_time.h> 46 #endif 47 48 #include <errno.h> 49 #include <stdlib.h> 50 #include <string.h> 51 52 #ifdef _WIN32 53 #undef HAVE_CLOCK_GETTIME 54 #endif 55 56 /** Delay for <b>msec</b> milliseconds. */ 57 void 58 tor_sleep_msec(int msec) 59 { 60 #ifdef _WIN32 61 Sleep(msec); 62 #elif defined(HAVE_TIME_H) 63 struct timespec ts = {msec / 1000, (msec % 1000) * 1000 * 1000}; 64 while (nanosleep(&ts, &ts) == -1 && errno == EINTR); 65 #elif defined(HAVE_USLEEP) 66 sleep(msec / 1000); 67 /* Some usleep()s hate sleeping more than 1 sec */ 68 usleep((msec % 1000) * 1000); 69 #elif defined(HAVE_SYS_SELECT_H) 70 struct timeval tv = { msec / 1000, (msec % 1000) * 1000}; 71 select(0, NULL, NULL, NULL, &tv); 72 #else 73 sleep(CEIL_DIV(msec, 1000)); 74 #endif /* defined(_WIN32) || ... */ 75 } 76 77 #define ONE_MILLION ((int64_t) (1000 * 1000)) 78 #define ONE_BILLION ((int64_t) (1000 * 1000 * 1000)) 79 80 /** True iff monotime_init has been called. */ 81 static int monotime_initialized = 0; 82 83 static monotime_t initialized_at; 84 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT 85 static monotime_coarse_t initialized_at_coarse; 86 #endif 87 88 #ifdef TOR_UNIT_TESTS 89 /** True if we are running unit tests and overriding the current monotonic 90 * time. Note that mocked monotonic time might not be monotonic. 91 */ 92 static int monotime_mocking_enabled = 0; 93 static monotime_t initialized_at_saved; 94 95 static int64_t mock_time_nsec = 0; 96 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT 97 static int64_t mock_time_nsec_coarse = 0; 98 static monotime_coarse_t initialized_at_coarse_saved; 99 #endif 100 101 void 102 monotime_enable_test_mocking(void) 103 { 104 if (BUG(monotime_initialized == 0)) { 105 monotime_init(); 106 } 107 108 tor_assert_nonfatal(monotime_mocking_enabled == 0); 109 monotime_mocking_enabled = 1; 110 memcpy(&initialized_at_saved, 111 &initialized_at, sizeof(monotime_t)); 112 memset(&initialized_at, 0, sizeof(monotime_t)); 113 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT 114 memcpy(&initialized_at_coarse_saved, 115 &initialized_at_coarse, sizeof(monotime_coarse_t)); 116 memset(&initialized_at_coarse, 0, sizeof(monotime_coarse_t)); 117 #endif 118 } 119 120 void 121 monotime_disable_test_mocking(void) 122 { 123 tor_assert_nonfatal(monotime_mocking_enabled == 1); 124 monotime_mocking_enabled = 0; 125 126 memcpy(&initialized_at, 127 &initialized_at_saved, sizeof(monotime_t)); 128 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT 129 memcpy(&initialized_at_coarse, 130 &initialized_at_coarse_saved, sizeof(monotime_coarse_t)); 131 #endif 132 } 133 134 void 135 monotime_set_mock_time_nsec(int64_t nsec) 136 { 137 tor_assert_nonfatal(monotime_mocking_enabled == 1); 138 mock_time_nsec = nsec; 139 } 140 141 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT 142 void 143 monotime_coarse_set_mock_time_nsec(int64_t nsec) 144 { 145 tor_assert_nonfatal(monotime_mocking_enabled == 1); 146 mock_time_nsec_coarse = nsec; 147 } 148 #endif /* defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */ 149 #endif /* defined(TOR_UNIT_TESTS) */ 150 151 /* "ratchet" functions for monotonic time. */ 152 153 #if defined(_WIN32) || defined(TOR_UNIT_TESTS) 154 155 /** Protected by lock: last value returned by monotime_get(). */ 156 static int64_t last_pctr = 0; 157 /** Protected by lock: offset we must add to monotonic time values. */ 158 static int64_t pctr_offset = 0; 159 /* If we are using GetTickCount(), how many times has it rolled over? */ 160 static uint32_t rollover_count = 0; 161 /* If we are using GetTickCount(), what's the last value it returned? */ 162 static int64_t last_tick_count = 0; 163 164 /** Helper for windows: Called with a sequence of times that are supposed 165 * to be monotonic; increments them as appropriate so that they actually 166 * _are_ monotonic. 167 * 168 * The returned time may be the same as the previous returned time. 169 * 170 * Caller must hold lock. */ 171 STATIC int64_t 172 ratchet_performance_counter(int64_t count_raw) 173 { 174 /* must hold lock */ 175 const int64_t count_adjusted = count_raw + pctr_offset; 176 177 if (PREDICT_UNLIKELY(count_adjusted < last_pctr)) { 178 /* Monotonicity failed! Pretend no time elapsed. */ 179 pctr_offset = last_pctr - count_raw; 180 return last_pctr; 181 } else { 182 last_pctr = count_adjusted; 183 return count_adjusted; 184 } 185 } 186 187 STATIC int64_t 188 ratchet_coarse_performance_counter(const int64_t count_raw) 189 { 190 int64_t count = count_raw + (((int64_t)rollover_count) << 32); 191 while (PREDICT_UNLIKELY(count < last_tick_count)) { 192 ++rollover_count; 193 count = count_raw + (((int64_t)rollover_count) << 32); 194 } 195 last_tick_count = count; 196 return count; 197 } 198 #endif /* defined(_WIN32) || defined(TOR_UNIT_TESTS) */ 199 200 #if defined(MONOTIME_USING_GETTIMEOFDAY) || defined(TOR_UNIT_TESTS) 201 static struct timeval last_timeofday = { 0, 0 }; 202 static struct timeval timeofday_offset = { 0, 0 }; 203 204 /** Helper for gettimeofday(): Called with a sequence of times that are 205 * supposed to be monotonic; increments them as appropriate so that they 206 * actually _are_ monotonic. 207 * 208 * The returned time may be the same as the previous returned time. 209 * 210 * Caller must hold lock. */ 211 STATIC void 212 ratchet_timeval(const struct timeval *timeval_raw, struct timeval *out) 213 { 214 /* must hold lock */ 215 timeradd(timeval_raw, &timeofday_offset, out); 216 if (PREDICT_UNLIKELY(timercmp(out, &last_timeofday, OP_LT))) { 217 /* time ran backwards. Instead, declare that no time occurred. */ 218 timersub(&last_timeofday, timeval_raw, &timeofday_offset); 219 memcpy(out, &last_timeofday, sizeof(struct timeval)); 220 } else { 221 memcpy(&last_timeofday, out, sizeof(struct timeval)); 222 } 223 } 224 #endif /* defined(MONOTIME_USING_GETTIMEOFDAY) || defined(TOR_UNIT_TESTS) */ 225 226 #ifdef TOR_UNIT_TESTS 227 /** For testing: reset all the ratchets */ 228 void 229 monotime_reset_ratchets_for_testing(void) 230 { 231 last_pctr = pctr_offset = last_tick_count = 0; 232 rollover_count = 0; 233 memset(&last_timeofday, 0, sizeof(struct timeval)); 234 memset(&timeofday_offset, 0, sizeof(struct timeval)); 235 } 236 #endif /* defined(TOR_UNIT_TESTS) */ 237 238 #ifdef __APPLE__ 239 240 /** Initialized on startup: tells is how to convert from ticks to 241 * nanoseconds. 242 */ 243 static struct mach_timebase_info mach_time_info; 244 static struct mach_timebase_info mach_time_info_msec_cvt; 245 static int32_t mach_time_msec_cvt_threshold; 246 static int monotime_shift = 0; 247 248 static void 249 monotime_init_internal(void) 250 { 251 tor_assert(!monotime_initialized); 252 int r = mach_timebase_info(&mach_time_info); 253 tor_assert(r == 0); 254 tor_assert(mach_time_info.denom != 0); 255 256 { 257 // We want to compute this, approximately: 258 // uint64_t ns_per_tick = mach_time_info.numer / mach_time_info.denom; 259 // uint64_t ticks_per_ms = ONE_MILLION / ns_per_tick; 260 // This calculation multiplies first, though, to improve accuracy. 261 uint64_t ticks_per_ms = (ONE_MILLION * mach_time_info.denom) 262 / mach_time_info.numer; 263 // requires that tor_log2(0) == 0. 264 monotime_shift = tor_log2(ticks_per_ms); 265 } 266 { 267 // For converting ticks to milliseconds in a 32-bit-friendly way, we 268 // will first right-shift by 20, and then multiply by 2048/1953, since 269 // (1<<20) * 1953/2048 is about 1e6. We precompute a new numerator and 270 // denominator here to avoid multiple multiplies. 271 mach_time_info_msec_cvt.numer = mach_time_info.numer * 2048; 272 mach_time_info_msec_cvt.denom = mach_time_info.denom * 1953; 273 // For any value above this amount, we should divide before multiplying, 274 // to avoid overflow. For a value below this, we should multiply 275 // before dividing, to improve accuracy. 276 mach_time_msec_cvt_threshold = INT32_MAX / mach_time_info_msec_cvt.numer; 277 } 278 } 279 280 /** 281 * Set "out" to the most recent monotonic time value. 282 * 283 * The returned time may be the same as the previous returned time. 284 */ 285 void 286 monotime_get(monotime_t *out) 287 { 288 #ifdef TOR_UNIT_TESTS 289 if (monotime_mocking_enabled) { 290 out->abstime_ = (mock_time_nsec * mach_time_info.denom) 291 / mach_time_info.numer; 292 return; 293 } 294 #endif /* defined(TOR_UNIT_TESTS) */ 295 out->abstime_ = mach_absolute_time(); 296 } 297 298 #if defined(HAVE_MACH_APPROXIMATE_TIME) 299 void 300 monotime_coarse_get(monotime_coarse_t *out) 301 { 302 #ifdef TOR_UNIT_TESTS 303 if (monotime_mocking_enabled) { 304 out->abstime_ = (mock_time_nsec_coarse * mach_time_info.denom) 305 / mach_time_info.numer; 306 return; 307 } 308 #endif /* defined(TOR_UNIT_TESTS) */ 309 out->abstime_ = mach_approximate_time(); 310 } 311 #endif /* defined(HAVE_MACH_APPROXIMATE_TIME) */ 312 313 /** 314 * Return the number of nanoseconds between <b>start</b> and <b>end</b>. 315 * 316 * The returned value may be equal to zero. 317 */ 318 int64_t 319 monotime_diff_nsec(const monotime_t *start, 320 const monotime_t *end) 321 { 322 if (BUG(mach_time_info.denom == 0)) { 323 monotime_init(); 324 } 325 const int64_t diff_ticks = end->abstime_ - start->abstime_; 326 const int64_t diff_nsec = 327 (diff_ticks * mach_time_info.numer) / mach_time_info.denom; 328 return diff_nsec; 329 } 330 331 int32_t 332 monotime_coarse_diff_msec32_(const monotime_coarse_t *start, 333 const monotime_coarse_t *end) 334 { 335 if (BUG(mach_time_info.denom == 0)) { 336 monotime_init(); 337 } 338 const int64_t diff_ticks = end->abstime_ - start->abstime_; 339 340 /* We already require in di_ops.c that right-shift performs a sign-extend. */ 341 const int32_t diff_microticks = (int32_t)(diff_ticks >> 20); 342 343 if (diff_microticks >= mach_time_msec_cvt_threshold) { 344 return (diff_microticks / mach_time_info_msec_cvt.denom) * 345 mach_time_info_msec_cvt.numer; 346 } else { 347 return (diff_microticks * mach_time_info_msec_cvt.numer) / 348 mach_time_info_msec_cvt.denom; 349 } 350 } 351 352 uint32_t 353 monotime_coarse_to_stamp(const monotime_coarse_t *t) 354 { 355 return (uint32_t)(t->abstime_ >> monotime_shift); 356 } 357 358 int 359 monotime_is_zero(const monotime_t *val) 360 { 361 return val->abstime_ == 0; 362 } 363 364 void 365 monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec) 366 { 367 const uint64_t nsec = msec * ONE_MILLION; 368 const uint64_t ticks = (nsec * mach_time_info.denom) / mach_time_info.numer; 369 out->abstime_ = val->abstime_ + ticks; 370 } 371 372 /* end of "__APPLE__" */ 373 #elif defined(HAVE_CLOCK_GETTIME) 374 375 #ifdef CLOCK_MONOTONIC_COARSE 376 /** 377 * Which clock should we use for coarse-grained monotonic time? By default 378 * this is CLOCK_MONOTONIC_COARSE, but it might not work -- for example, 379 * if we're compiled with newer Linux headers and then we try to run on 380 * an old Linux kernel. In that case, we will fall back to CLOCK_MONOTONIC. 381 */ 382 static int clock_monotonic_coarse = CLOCK_MONOTONIC_COARSE; 383 #endif /* defined(CLOCK_MONOTONIC_COARSE) */ 384 385 static void 386 monotime_init_internal(void) 387 { 388 #ifdef CLOCK_MONOTONIC_COARSE 389 struct timespec ts; 390 if (clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) < 0) { 391 log_info(LD_GENERAL, "CLOCK_MONOTONIC_COARSE isn't working (%s); " 392 "falling back to CLOCK_MONOTONIC.", strerror(errno)); 393 clock_monotonic_coarse = CLOCK_MONOTONIC; 394 } 395 #endif /* defined(CLOCK_MONOTONIC_COARSE) */ 396 } 397 398 void 399 monotime_get(monotime_t *out) 400 { 401 #ifdef TOR_UNIT_TESTS 402 if (monotime_mocking_enabled) { 403 out->ts_.tv_sec = (time_t) (mock_time_nsec / ONE_BILLION); 404 out->ts_.tv_nsec = (int) (mock_time_nsec % ONE_BILLION); 405 return; 406 } 407 #endif /* defined(TOR_UNIT_TESTS) */ 408 int r = clock_gettime(CLOCK_MONOTONIC, &out->ts_); 409 tor_assert(r == 0); 410 } 411 412 #ifdef CLOCK_MONOTONIC_COARSE 413 void 414 monotime_coarse_get(monotime_coarse_t *out) 415 { 416 #ifdef TOR_UNIT_TESTS 417 if (monotime_mocking_enabled) { 418 out->ts_.tv_sec = (time_t) (mock_time_nsec_coarse / ONE_BILLION); 419 out->ts_.tv_nsec = (int) (mock_time_nsec_coarse % ONE_BILLION); 420 return; 421 } 422 #endif /* defined(TOR_UNIT_TESTS) */ 423 int r = clock_gettime(clock_monotonic_coarse, &out->ts_); 424 if (PREDICT_UNLIKELY(r < 0) && 425 errno == EINVAL && 426 clock_monotonic_coarse == CLOCK_MONOTONIC_COARSE) { 427 /* We should have caught this at startup in monotime_init_internal! 428 */ 429 log_warn(LD_BUG, "Falling back to non-coarse monotonic time %s initial " 430 "system start?", monotime_initialized?"after":"without"); 431 clock_monotonic_coarse = CLOCK_MONOTONIC; 432 r = clock_gettime(clock_monotonic_coarse, &out->ts_); 433 } 434 435 tor_assert(r == 0); 436 } 437 #endif /* defined(CLOCK_MONOTONIC_COARSE) */ 438 439 int64_t 440 monotime_diff_nsec(const monotime_t *start, 441 const monotime_t *end) 442 { 443 const int64_t diff_sec = end->ts_.tv_sec - start->ts_.tv_sec; 444 const int64_t diff_nsec = diff_sec * ONE_BILLION + 445 (end->ts_.tv_nsec - start->ts_.tv_nsec); 446 447 return diff_nsec; 448 } 449 450 int32_t 451 monotime_coarse_diff_msec32_(const monotime_coarse_t *start, 452 const monotime_coarse_t *end) 453 { 454 const int32_t diff_sec = (int32_t)(end->ts_.tv_sec - start->ts_.tv_sec); 455 const int32_t diff_nsec = (int32_t)(end->ts_.tv_nsec - start->ts_.tv_nsec); 456 return diff_sec * 1000 + diff_nsec / ONE_MILLION; 457 } 458 459 /* This value is ONE_BILLION >> 20. */ 460 static const uint32_t STAMP_TICKS_PER_SECOND = 953; 461 462 uint32_t 463 monotime_coarse_to_stamp(const monotime_coarse_t *t) 464 { 465 uint32_t nsec = (uint32_t)t->ts_.tv_nsec; 466 uint32_t sec = (uint32_t)t->ts_.tv_sec; 467 468 return (sec * STAMP_TICKS_PER_SECOND) + (nsec >> 20); 469 } 470 471 int 472 monotime_is_zero(const monotime_t *val) 473 { 474 return val->ts_.tv_sec == 0 && val->ts_.tv_nsec == 0; 475 } 476 477 void 478 monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec) 479 { 480 const uint32_t sec = msec / 1000; 481 const uint32_t msec_remainder = msec % 1000; 482 out->ts_.tv_sec = val->ts_.tv_sec + sec; 483 out->ts_.tv_nsec = val->ts_.tv_nsec + (msec_remainder * ONE_MILLION); 484 if (out->ts_.tv_nsec > ONE_BILLION) { 485 out->ts_.tv_nsec -= ONE_BILLION; 486 out->ts_.tv_sec += 1; 487 } 488 } 489 490 /* end of "HAVE_CLOCK_GETTIME" */ 491 #elif defined (_WIN32) 492 493 /** Result of QueryPerformanceFrequency, in terms needed to 494 * convert ticks to nanoseconds. */ 495 static int64_t nsec_per_tick_numer = 1; 496 static int64_t nsec_per_tick_denom = 1; 497 498 /** Lock to protect last_pctr and pctr_offset */ 499 static CRITICAL_SECTION monotime_lock; 500 /** Lock to protect rollover_count and last_tick_count */ 501 static CRITICAL_SECTION monotime_coarse_lock; 502 503 typedef ULONGLONG (WINAPI *GetTickCount64_fn_t)(void); 504 static GetTickCount64_fn_t GetTickCount64_fn = NULL; 505 506 static void 507 monotime_init_internal(void) 508 { 509 tor_assert(!monotime_initialized); 510 BOOL ok = InitializeCriticalSectionAndSpinCount(&monotime_lock, 200); 511 tor_assert(ok); 512 ok = InitializeCriticalSectionAndSpinCount(&monotime_coarse_lock, 200); 513 tor_assert(ok); 514 LARGE_INTEGER li; 515 ok = QueryPerformanceFrequency(&li); 516 tor_assert(ok); 517 tor_assert(li.QuadPart); 518 519 uint64_t n = ONE_BILLION; 520 uint64_t d = li.QuadPart; 521 /* We need to simplify this or we'll probably overflow the int64. */ 522 simplify_fraction64(&n, &d); 523 tor_assert(n <= INT64_MAX); 524 tor_assert(d <= INT64_MAX); 525 526 nsec_per_tick_numer = (int64_t) n; 527 nsec_per_tick_denom = (int64_t) d; 528 529 last_pctr = 0; 530 pctr_offset = 0; 531 532 HANDLE h = load_windows_system_library(TEXT("kernel32.dll")); 533 if (h) { 534 GetTickCount64_fn = (GetTickCount64_fn_t) (void(*)(void)) 535 GetProcAddress(h, "GetTickCount64"); 536 } 537 // We can't call FreeLibrary(h) here, because freeing the handle may 538 // unload the library, and cause future calls to GetTickCount64_fn() 539 // to fail. See 29642 for details. 540 } 541 542 void 543 monotime_get(monotime_t *out) 544 { 545 if (BUG(monotime_initialized == 0)) { 546 monotime_init(); 547 } 548 549 #ifdef TOR_UNIT_TESTS 550 if (monotime_mocking_enabled) { 551 out->pcount_ = (mock_time_nsec * nsec_per_tick_denom) 552 / nsec_per_tick_numer; 553 return; 554 } 555 #endif /* defined(TOR_UNIT_TESTS) */ 556 557 /* Alas, QueryPerformanceCounter is not always monotonic: see bug list at 558 559 https://www.python.org/dev/peps/pep-0418/#windows-queryperformancecounter 560 */ 561 562 EnterCriticalSection(&monotime_lock); 563 LARGE_INTEGER res; 564 BOOL ok = QueryPerformanceCounter(&res); 565 tor_assert(ok); 566 const int64_t count_raw = res.QuadPart; 567 out->pcount_ = ratchet_performance_counter(count_raw); 568 LeaveCriticalSection(&monotime_lock); 569 } 570 571 void 572 monotime_coarse_get(monotime_coarse_t *out) 573 { 574 #ifdef TOR_UNIT_TESTS 575 if (monotime_mocking_enabled) { 576 out->tick_count_ = mock_time_nsec_coarse / ONE_MILLION; 577 return; 578 } 579 #endif /* defined(TOR_UNIT_TESTS) */ 580 581 if (GetTickCount64_fn) { 582 out->tick_count_ = (int64_t)GetTickCount64_fn(); 583 } else { 584 EnterCriticalSection(&monotime_coarse_lock); 585 DWORD tick = GetTickCount(); 586 out->tick_count_ = ratchet_coarse_performance_counter(tick); 587 LeaveCriticalSection(&monotime_coarse_lock); 588 } 589 } 590 591 int64_t 592 monotime_diff_nsec(const monotime_t *start, 593 const monotime_t *end) 594 { 595 if (BUG(monotime_initialized == 0)) { 596 monotime_init(); 597 } 598 const int64_t diff_ticks = end->pcount_ - start->pcount_; 599 return (diff_ticks * nsec_per_tick_numer) / nsec_per_tick_denom; 600 } 601 602 int64_t 603 monotime_coarse_diff_msec(const monotime_coarse_t *start, 604 const monotime_coarse_t *end) 605 { 606 const int64_t diff_ticks = end->tick_count_ - start->tick_count_; 607 return diff_ticks; 608 } 609 610 int32_t 611 monotime_coarse_diff_msec32_(const monotime_coarse_t *start, 612 const monotime_coarse_t *end) 613 { 614 return (int32_t)monotime_coarse_diff_msec(start, end); 615 } 616 617 int64_t 618 monotime_coarse_diff_usec(const monotime_coarse_t *start, 619 const monotime_coarse_t *end) 620 { 621 return monotime_coarse_diff_msec(start, end) * 1000; 622 } 623 624 int64_t 625 monotime_coarse_diff_nsec(const monotime_coarse_t *start, 626 const monotime_coarse_t *end) 627 { 628 return monotime_coarse_diff_msec(start, end) * ONE_MILLION; 629 } 630 631 static const uint32_t STAMP_TICKS_PER_SECOND = 1000; 632 633 uint32_t 634 monotime_coarse_to_stamp(const monotime_coarse_t *t) 635 { 636 return (uint32_t) t->tick_count_; 637 } 638 639 int 640 monotime_is_zero(const monotime_t *val) 641 { 642 return val->pcount_ == 0; 643 } 644 645 int 646 monotime_coarse_is_zero(const monotime_coarse_t *val) 647 { 648 return val->tick_count_ == 0; 649 } 650 651 void 652 monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec) 653 { 654 const uint64_t nsec = msec * ONE_MILLION; 655 const uint64_t ticks = (nsec * nsec_per_tick_denom) / nsec_per_tick_numer; 656 out->pcount_ = val->pcount_ + ticks; 657 } 658 659 void 660 monotime_coarse_add_msec(monotime_coarse_t *out, const monotime_coarse_t *val, 661 uint32_t msec) 662 { 663 out->tick_count_ = val->tick_count_ + msec; 664 } 665 666 /* end of "_WIN32" */ 667 #elif defined(MONOTIME_USING_GETTIMEOFDAY) 668 669 static tor_mutex_t monotime_lock; 670 671 /** Initialize the monotonic timer subsystem. */ 672 static void 673 monotime_init_internal(void) 674 { 675 tor_assert(!monotime_initialized); 676 tor_mutex_init(&monotime_lock); 677 } 678 679 void 680 monotime_get(monotime_t *out) 681 { 682 if (BUG(monotime_initialized == 0)) { 683 monotime_init(); 684 } 685 686 tor_mutex_acquire(&monotime_lock); 687 struct timeval timeval_raw; 688 tor_gettimeofday(&timeval_raw); 689 ratchet_timeval(&timeval_raw, &out->tv_); 690 tor_mutex_release(&monotime_lock); 691 } 692 693 int64_t 694 monotime_diff_nsec(const monotime_t *start, 695 const monotime_t *end) 696 { 697 struct timeval diff; 698 timersub(&end->tv_, &start->tv_, &diff); 699 return (diff.tv_sec * ONE_BILLION + diff.tv_usec * 1000); 700 } 701 702 int32_t 703 monotime_coarse_diff_msec32_(const monotime_coarse_t *start, 704 const monotime_coarse_t *end) 705 { 706 struct timeval diff; 707 timersub(&end->tv_, &start->tv_, &diff); 708 return diff.tv_sec * 1000 + diff.tv_usec / 1000; 709 } 710 711 /* This value is ONE_MILLION >> 10. */ 712 static const uint32_t STAMP_TICKS_PER_SECOND = 976; 713 714 uint32_t 715 monotime_coarse_to_stamp(const monotime_coarse_t *t) 716 { 717 const uint32_t usec = (uint32_t)t->tv_.tv_usec; 718 const uint32_t sec = (uint32_t)t->tv_.tv_sec; 719 return (sec * STAMP_TICKS_PER_SECOND) | (nsec >> 10); 720 } 721 722 int 723 monotime_is_zero(const monotime_t *val) 724 { 725 return val->tv_.tv_sec == 0 && val->tv_.tv_usec == 0; 726 } 727 728 void 729 monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec) 730 { 731 const uint32_t sec = msec / 1000; 732 const uint32_t msec_remainder = msec % 1000; 733 out->tv_.tv_sec = val->tv_.tv_sec + sec; 734 out->tv_.tv_usec = val->tv_.tv_nsec + (msec_remainder * 1000); 735 if (out->tv_.tv_usec > ONE_MILLION) { 736 out->tv_.tv_usec -= ONE_MILLION; 737 out->tv_.tv_sec += 1; 738 } 739 } 740 741 /* end of "MONOTIME_USING_GETTIMEOFDAY" */ 742 #else 743 #error "No way to implement monotonic timers." 744 #endif /* defined(__APPLE__) || ... */ 745 746 /** 747 * Initialize the monotonic timer subsystem. Must be called before any 748 * monotonic timer functions. This function is idempotent. 749 */ 750 void 751 monotime_init(void) 752 { 753 if (!monotime_initialized) { 754 monotime_init_internal(); 755 monotime_initialized = 1; 756 monotime_get(&initialized_at); 757 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT 758 monotime_coarse_get(&initialized_at_coarse); 759 #endif 760 } 761 } 762 763 void 764 monotime_zero(monotime_t *out) 765 { 766 memset(out, 0, sizeof(*out)); 767 } 768 #ifdef MONOTIME_COARSE_TYPE_IS_DIFFERENT 769 void 770 monotime_coarse_zero(monotime_coarse_t *out) 771 { 772 memset(out, 0, sizeof(*out)); 773 } 774 #endif /* defined(MONOTIME_COARSE_TYPE_IS_DIFFERENT) */ 775 776 int64_t 777 monotime_diff_usec(const monotime_t *start, 778 const monotime_t *end) 779 { 780 const int64_t nsec = monotime_diff_nsec(start, end); 781 return CEIL_DIV(nsec, 1000); 782 } 783 784 int64_t 785 monotime_diff_msec(const monotime_t *start, 786 const monotime_t *end) 787 { 788 const int64_t nsec = monotime_diff_nsec(start, end); 789 return CEIL_DIV(nsec, ONE_MILLION); 790 } 791 792 uint64_t 793 monotime_absolute_nsec(void) 794 { 795 monotime_t now; 796 if (BUG(monotime_initialized == 0)) { 797 monotime_init(); 798 } 799 800 monotime_get(&now); 801 return monotime_diff_nsec(&initialized_at, &now); 802 } 803 804 MOCK_IMPL(uint64_t, 805 monotime_absolute_usec,(void)) 806 { 807 return monotime_absolute_nsec() / 1000; 808 } 809 810 uint64_t 811 monotime_absolute_msec(void) 812 { 813 return monotime_absolute_nsec() / ONE_MILLION; 814 } 815 816 uint64_t 817 monotime_absolute_sec(void) 818 { 819 return monotime_absolute_nsec() / ONE_BILLION; 820 } 821 822 #ifdef MONOTIME_COARSE_FN_IS_DIFFERENT 823 uint64_t 824 monotime_coarse_absolute_nsec(void) 825 { 826 if (BUG(monotime_initialized == 0)) { 827 monotime_init(); 828 } 829 830 monotime_coarse_t now; 831 monotime_coarse_get(&now); 832 return monotime_coarse_diff_nsec(&initialized_at_coarse, &now); 833 } 834 835 uint64_t 836 monotime_coarse_absolute_usec(void) 837 { 838 return monotime_coarse_absolute_nsec() / 1000; 839 } 840 841 uint64_t 842 monotime_coarse_absolute_msec(void) 843 { 844 return monotime_coarse_absolute_nsec() / ONE_MILLION; 845 } 846 847 uint64_t 848 monotime_coarse_absolute_sec(void) 849 { 850 /* Note: Right now I'm not too concerned about 64-bit division, but if this 851 * ever becomes a hotspot we need to optimize, we can modify this to grab 852 * tv_sec directly from CLOCK_MONOTONIC_COARSE on linux at least. Right now 853 * I'm choosing to make this simpler and easier to test, but this 854 * optimization is available easily if we need it. */ 855 return monotime_coarse_absolute_nsec() / ONE_BILLION; 856 } 857 #else /* !defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */ 858 #define initialized_at_coarse initialized_at 859 #endif /* defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */ 860 861 /** 862 * Return the current time "stamp" as described by monotime_coarse_to_stamp. 863 */ 864 uint32_t 865 monotime_coarse_get_stamp(void) 866 { 867 monotime_coarse_t now; 868 monotime_coarse_get(&now); 869 return monotime_coarse_to_stamp(&now); 870 } 871 872 #ifdef __APPLE__ 873 uint64_t 874 monotime_coarse_stamp_units_to_approx_msec(uint64_t units) 875 { 876 /* Recover as much precision as we can. */ 877 uint64_t abstime_diff = (units << monotime_shift); 878 return (abstime_diff * mach_time_info.numer) / 879 (mach_time_info.denom * ONE_MILLION); 880 } 881 uint64_t 882 monotime_msec_to_approx_coarse_stamp_units(uint64_t msec) 883 { 884 uint64_t abstime_val = 885 (((uint64_t)msec) * ONE_MILLION * mach_time_info.denom) / 886 mach_time_info.numer; 887 return abstime_val >> monotime_shift; 888 } 889 #else /* !defined(__APPLE__) */ 890 uint64_t 891 monotime_coarse_stamp_units_to_approx_msec(uint64_t units) 892 { 893 return (units * 1000) / STAMP_TICKS_PER_SECOND; 894 } 895 uint64_t 896 monotime_msec_to_approx_coarse_stamp_units(uint64_t msec) 897 { 898 return (msec * STAMP_TICKS_PER_SECOND) / 1000; 899 } 900 #endif /* defined(__APPLE__) */