tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Now.cpp (2990B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "Now.h"
      8 
      9 #ifdef XP_WIN
     10 #  include "mozilla/DynamicallyLinkedFunctionPtr.h"
     11 #endif  // XP_WIN
     12 
     13 #include <stdint.h>
     14 
     15 #include "mozilla/TimeStamp.h"
     16 #include "mozilla/Maybe.h"
     17 
     18 namespace mozilla {
     19 
     20 // Apple things
     21 #if defined(__APPLE__) && defined(__MACH__)
     22 #  include <time.h>
     23 #  include <sys/time.h>
     24 #  include <sys/types.h>
     25 #  include <mach/mach_time.h>
     26 
     27 static constexpr uint64_t kNSperMS = 1000000;
     28 
     29 Maybe<uint64_t> NowExcludingSuspendMs() {
     30  return Some(clock_gettime_nsec_np(CLOCK_UPTIME_RAW) / kNSperMS);
     31 }
     32 
     33 Maybe<uint64_t> NowIncludingSuspendMs() {
     34  return Some(clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW) / kNSperMS);
     35 }
     36 
     37 #elif defined(XP_WIN)
     38 
     39 // Number of hundreds of nanoseconds in a millisecond
     40 static constexpr uint64_t kHNSperMS = 10000;
     41 
     42 Maybe<uint64_t> NowExcludingSuspendMs() {
     43  ULONGLONG interrupt_time;
     44  if (!QueryUnbiasedInterruptTime(&interrupt_time)) {
     45    return Nothing();
     46  }
     47  return Some(interrupt_time / kHNSperMS);
     48 }
     49 
     50 Maybe<uint64_t> NowIncludingSuspendMs() {
     51  static const mozilla::StaticDynamicallyLinkedFunctionPtr<void(WINAPI*)(
     52      PULONGLONG)>
     53      pQueryInterruptTime(L"KernelBase.dll", "QueryInterruptTime");
     54  if (!pQueryInterruptTime) {
     55    // On Windows, this does include the time the computer was suspended so it's
     56    // an adequate fallback.
     57    TimeStamp processCreation = TimeStamp::ProcessCreation();
     58    TimeStamp now = TimeStamp::Now();
     59    if (!processCreation.IsNull() && !now.IsNull()) {
     60      return Some(uint64_t((now - processCreation).ToMilliseconds()));
     61    } else {
     62      return Nothing();
     63    }
     64  }
     65  ULONGLONG interrupt_time;
     66  pQueryInterruptTime(&interrupt_time);
     67  return Some(interrupt_time / kHNSperMS);
     68 }
     69 
     70 #elif defined(XP_UNIX)  // including BSDs and Android
     71 #  include <time.h>
     72 
     73 // Number of nanoseconds in a millisecond.
     74 static constexpr uint64_t kNSperMS = 1000000;
     75 
     76 static uint64_t TimespecToMilliseconds(struct timespec aTs) {
     77  return aTs.tv_sec * 1000 + aTs.tv_nsec / kNSperMS;
     78 }
     79 
     80 Maybe<uint64_t> NowExcludingSuspendMs() {
     81  struct timespec ts = {0};
     82 
     83 #  ifdef XP_OPENBSD
     84  if (clock_gettime(CLOCK_UPTIME, &ts)) {
     85 #  else
     86  if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
     87 #  endif
     88    return Nothing();
     89  }
     90  return Some(TimespecToMilliseconds(ts));
     91 }
     92 
     93 Maybe<uint64_t> NowIncludingSuspendMs() {
     94 #  ifndef CLOCK_BOOTTIME
     95  return Nothing();
     96 #  else
     97  struct timespec ts = {0};
     98 
     99  if (clock_gettime(CLOCK_BOOTTIME, &ts)) {
    100    return Nothing();
    101  }
    102  return Some(TimespecToMilliseconds(ts));
    103 #  endif
    104 }
    105 
    106 #else  // catch all
    107 
    108 Maybe<uint64_t> NowExcludingSuspendMs() { return Nothing(); }
    109 Maybe<uint64_t> NowIncludingSuspendMs() { return Nothing(); }
    110 
    111 #endif
    112 
    113 }  // namespace mozilla