From 0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:47:29 +0200 Subject: Adding upstream version 115.8.0esr. Signed-off-by: Daniel Baumann --- mozglue/misc/Uptime.cpp | 155 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 mozglue/misc/Uptime.cpp (limited to 'mozglue/misc/Uptime.cpp') diff --git a/mozglue/misc/Uptime.cpp b/mozglue/misc/Uptime.cpp new file mode 100644 index 0000000000..924b154359 --- /dev/null +++ b/mozglue/misc/Uptime.cpp @@ -0,0 +1,155 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "Uptime.h" + +#ifdef XP_WIN +# include "mozilla/DynamicallyLinkedFunctionPtr.h" +#endif // XP_WIN + +#include + +#include "mozilla/TimeStamp.h" +#include "mozilla/Maybe.h" +#include "mozilla/Assertions.h" + +using namespace mozilla; + +namespace { + +Maybe NowIncludingSuspendMs(); +Maybe NowExcludingSuspendMs(); +static Maybe mStartExcludingSuspendMs; +static Maybe mStartIncludingSuspendMs; + +// Apple things +#if defined(__APPLE__) && defined(__MACH__) +# include +# include +# include +# include + +const uint64_t kNSperMS = 1000000; + +Maybe NowExcludingSuspendMs() { + return Some(clock_gettime_nsec_np(CLOCK_UPTIME_RAW) / kNSperMS); +} + +Maybe NowIncludingSuspendMs() { + return Some(clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW) / kNSperMS); +} + +#elif defined(XP_WIN) + +// Number of hundreds of nanoseconds in a millisecond +static constexpr uint64_t kHNSperMS = 10000; + +Maybe NowExcludingSuspendMs() { + ULONGLONG interrupt_time; + if (!QueryUnbiasedInterruptTime(&interrupt_time)) { + return Nothing(); + } + return Some(interrupt_time / kHNSperMS); +} + +Maybe NowIncludingSuspendMs() { + static const mozilla::StaticDynamicallyLinkedFunctionPtr + pQueryInterruptTime(L"KernelBase.dll", "QueryInterruptTime"); + if (!pQueryInterruptTime) { + // On Windows, this does include the time the computer was suspended so it's + // an adequate fallback. + TimeStamp processCreation = TimeStamp::ProcessCreation(); + TimeStamp now = TimeStamp::Now(); + if (!processCreation.IsNull() && !now.IsNull()) { + return Some(uint64_t((now - processCreation).ToMilliseconds())); + } else { + return Nothing(); + } + } + ULONGLONG interrupt_time; + pQueryInterruptTime(&interrupt_time); + return Some(interrupt_time / kHNSperMS); +} + +#elif defined(XP_UNIX) // including BSDs and Android +# include + +// Number of nanoseconds in a millisecond. +static constexpr uint64_t kNSperMS = 1000000; + +uint64_t TimespecToMilliseconds(struct timespec aTs) { + return aTs.tv_sec * 1000 + aTs.tv_nsec / kNSperMS; +} + +Maybe NowExcludingSuspendMs() { + struct timespec ts = {0}; + +# ifdef XP_OPENBSD + if (clock_gettime(CLOCK_UPTIME, &ts)) { +# else + if (clock_gettime(CLOCK_MONOTONIC, &ts)) { +# endif + return Nothing(); + } + return Some(TimespecToMilliseconds(ts)); +} + +Maybe NowIncludingSuspendMs() { +# ifndef CLOCK_BOOTTIME + return Nothing(); +# else + struct timespec ts = {0}; + + if (clock_gettime(CLOCK_BOOTTIME, &ts)) { + return Nothing(); + } + return Some(TimespecToMilliseconds(ts)); +# endif +} + +#else // catch all + +Maybe NowExcludingSuspendMs() { return Nothing(); } +Maybe NowIncludingSuspendMs() { return Nothing(); } + +#endif + +}; // anonymous namespace + +namespace mozilla { + +void InitializeUptime() { + MOZ_RELEASE_ASSERT(mStartIncludingSuspendMs.isNothing() && + mStartExcludingSuspendMs.isNothing(), + "Must not be called more than once"); + mStartIncludingSuspendMs = NowIncludingSuspendMs(); + mStartExcludingSuspendMs = NowExcludingSuspendMs(); +} + +Maybe ProcessUptimeMs() { + if (!mStartIncludingSuspendMs) { + return Nothing(); + } + Maybe maybeNow = NowIncludingSuspendMs(); + if (!maybeNow) { + return Nothing(); + } + return Some(maybeNow.value() - mStartIncludingSuspendMs.value()); +} + +Maybe ProcessUptimeExcludingSuspendMs() { + if (!mStartExcludingSuspendMs) { + return Nothing(); + } + Maybe maybeNow = NowExcludingSuspendMs(); + if (!maybeNow) { + return Nothing(); + } + return Some(maybeNow.value() - mStartExcludingSuspendMs.value()); +} + +}; // namespace mozilla -- cgit v1.2.3