mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
Bug 1205985
- Implement something to get the process uptime with and without the time the device was suspended. r=haik,dmajor,jld
Differential Revision: https://phabricator.services.mozilla.com/D99138
This commit is contained in:
parent
b19b4aa8ba
commit
b8fa268285
@ -10,6 +10,7 @@
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Uptime.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@ -36,6 +37,9 @@ struct TimeStampInitialization {
|
||||
TimeStampInitialization() {
|
||||
TimeStamp::Startup();
|
||||
mFirstTimeStamp = TimeStamp::Now();
|
||||
// On Windows < 10, initializing the uptime requires `mFirstTimeStamp` to be
|
||||
// valid.
|
||||
mozilla::InitializeUptime();
|
||||
};
|
||||
|
||||
~TimeStampInitialization() { TimeStamp::Shutdown(); };
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Uptime.h"
|
||||
|
||||
// Estimate of the smallest duration of time we can measure.
|
||||
static uint64_t sResolution;
|
||||
|
@ -49,6 +49,7 @@
|
||||
|
||||
#include "mozilla/Sprintf.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Uptime.h"
|
||||
#include <pthread.h>
|
||||
|
||||
// Estimate of the smallest duration of time we can measure.
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "mozilla/DynamicallyLinkedFunctionPtr.h"
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Uptime.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
150
mozglue/misc/Uptime.cpp
Normal file
150
mozglue/misc/Uptime.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
/* -*- 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 <stdint.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
namespace {
|
||||
|
||||
Maybe<uint64_t> NowIncludingSuspendMs();
|
||||
Maybe<uint64_t> NowExcludingSuspendMs();
|
||||
static Maybe<uint64_t> mStartExcludingSuspendMs;
|
||||
static Maybe<uint64_t> mStartIncludingSuspendMs;
|
||||
|
||||
// Apple things
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
# include <time.h>
|
||||
# include <sys/time.h>
|
||||
# include <sys/types.h>
|
||||
# include <mach/mach_time.h>
|
||||
|
||||
const uint64_t kNSperMS = 1000000;
|
||||
|
||||
Maybe<uint64_t> NowExcludingSuspendMs() {
|
||||
return Some(clock_gettime_nsec_np(CLOCK_UPTIME_RAW) / kNSperMS);
|
||||
}
|
||||
|
||||
Maybe<uint64_t> NowIncludingSuspendMs() {
|
||||
return Some(clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW) / kNSperMS);
|
||||
}
|
||||
|
||||
#endif // macOS
|
||||
|
||||
#if defined(XP_WIN)
|
||||
|
||||
// Number of hundreds of nanoseconds in a millisecond
|
||||
static constexpr uint64_t kHNSperMS = 10000;
|
||||
|
||||
Maybe<uint64_t> NowExcludingSuspendMs() {
|
||||
ULONGLONG interrupt_time;
|
||||
if (!QueryUnbiasedInterruptTime(&interrupt_time)) {
|
||||
return Nothing();
|
||||
}
|
||||
return Some(interrupt_time / kHNSperMS);
|
||||
}
|
||||
|
||||
Maybe<uint64_t> NowIncludingSuspendMs() {
|
||||
static const mozilla::StaticDynamicallyLinkedFunctionPtr<void(WINAPI*)(
|
||||
PULONGLONG)>
|
||||
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);
|
||||
}
|
||||
#endif // XP_WIN
|
||||
|
||||
#if defined(XP_LINUX) // including Android
|
||||
# include <time.h>
|
||||
|
||||
// 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<uint64_t> NowExcludingSuspendMs() {
|
||||
struct timespec ts = {0};
|
||||
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
|
||||
return Nothing();
|
||||
}
|
||||
return Some(TimespecToMilliseconds(ts));
|
||||
}
|
||||
|
||||
Maybe<uint64_t> NowIncludingSuspendMs() {
|
||||
# ifndef CLOCK_BOOTTIME
|
||||
return Nothing();
|
||||
# else
|
||||
struct timespec ts = {0};
|
||||
|
||||
if (clock_gettime(CLOCK_BOOTTIME, &ts)) {
|
||||
return Nothing();
|
||||
}
|
||||
return Some(TimespecToMilliseconds(ts));
|
||||
# endif
|
||||
}
|
||||
|
||||
#endif // XP_LINUX
|
||||
|
||||
}; // 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<uint64_t> ProcessUptimeMs() {
|
||||
if (!mStartIncludingSuspendMs) {
|
||||
return Nothing();
|
||||
}
|
||||
Maybe<uint64_t> maybeNow = NowIncludingSuspendMs();
|
||||
if (!maybeNow) {
|
||||
return Nothing();
|
||||
}
|
||||
return Some(maybeNow.value() - mStartIncludingSuspendMs.value());
|
||||
}
|
||||
|
||||
Maybe<uint64_t> ProcessUptimeExcludingSuspendMs() {
|
||||
if (!mStartExcludingSuspendMs) {
|
||||
return Nothing();
|
||||
}
|
||||
Maybe<uint64_t> maybeNow = NowExcludingSuspendMs();
|
||||
if (!maybeNow) {
|
||||
return Nothing();
|
||||
}
|
||||
return Some(maybeNow.value() - mStartExcludingSuspendMs.value());
|
||||
}
|
||||
|
||||
}; // namespace mozilla
|
26
mozglue/misc/Uptime.h
Normal file
26
mozglue/misc/Uptime.h
Normal file
@ -0,0 +1,26 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#ifndef mozilla_Uptime_h
|
||||
#define mozilla_Uptime_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mozilla/Maybe.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// Called at the beginning of the process from TimeStamp::Startup.
|
||||
MFBT_API void InitializeUptime();
|
||||
// Returns the number of milliseconds the calling process has lived for.
|
||||
MFBT_API Maybe<uint64_t> ProcessUptimeMs();
|
||||
// Returns the number of milliseconds the calling process has lived for,
|
||||
// excluding the time period the system was suspended.
|
||||
MFBT_API Maybe<uint64_t> ProcessUptimeExcludingSuspendMs();
|
||||
|
||||
}; // namespace mozilla
|
||||
|
||||
#endif // mozilla_Uptime_h
|
@ -16,6 +16,7 @@ EXPORTS.mozilla += [
|
||||
"Printf.h",
|
||||
"StackWalk.h",
|
||||
"TimeStamp.h",
|
||||
"Uptime.h",
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.glue += [
|
||||
@ -37,6 +38,7 @@ SOURCES += [
|
||||
"Printf.cpp",
|
||||
"StackWalk.cpp",
|
||||
"TimeStamp.cpp",
|
||||
"Uptime.cpp",
|
||||
]
|
||||
|
||||
OS_LIBS += CONFIG["REALTIME_LIBS"]
|
||||
|
@ -653,6 +653,9 @@ class SandboxPolicyCommon : public SandboxPolicyBase {
|
||||
// Allow clock_gettime on a thread.
|
||||
// 4 -> CPUCLOCK_PERTHREAD_MASK. 2 -> CPUCLOCK_SCHED.
|
||||
.ElseIf((clk_id & 7u) == (4u | 2u), Allow())
|
||||
#endif
|
||||
#ifdef CLOCK_BOOTTIME
|
||||
.ElseIf(clk_id == CLOCK_BOOTTIME, Allow())
|
||||
#endif
|
||||
.Else(InvalidSyscall());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user