123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- // Copyright 2022 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "services/device/compute_pressure/core_times.h"
- #include "base/check_op.h"
- namespace device {
- CoreTimes::CoreTimes(const std::initializer_list<uint64_t>& times) {
- DCHECK_EQ(times.size(), 10u);
- size_t i = 0;
- for (auto value : times)
- times_[i++] = value;
- }
- void CoreTimes::set_user(uint64_t time) {
- if (times_[0] < time)
- times_[0] = time;
- }
- void CoreTimes::set_nice(uint64_t time) {
- if (times_[1] < time)
- times_[1] = time;
- }
- void CoreTimes::set_system(uint64_t time) {
- if (times_[2] < time)
- times_[2] = time;
- }
- void CoreTimes::set_idle(uint64_t time) {
- if (times_[3] < time)
- times_[3] = time;
- }
- void CoreTimes::set_iowait(uint64_t time) {
- if (times_[4] < time)
- times_[4] = time;
- }
- void CoreTimes::set_irq(uint64_t time) {
- if (times_[5] < time)
- times_[5] = time;
- }
- void CoreTimes::set_softirq(uint64_t time) {
- if (times_[6] < time)
- times_[6] = time;
- }
- void CoreTimes::set_steal(uint64_t time) {
- if (times_[7] < time)
- times_[7] = time;
- }
- void CoreTimes::set_guest(uint64_t time) {
- if (times_[8] < time)
- times_[8] = time;
- }
- void CoreTimes::set_guest_nice(uint64_t time) {
- if (times_[9] < time)
- times_[9] = time;
- }
- double CoreTimes::TimeUtilization(const CoreTimes& baseline) const {
- // Each of the blocks below consists of a check and a subtraction. The check
- // is used to bail on invalid input (/proc/stat counters should never
- // decrease over time).
- //
- // The check is also essential for the correctness of the subtraction -- the
- // result of the subtraction is stored in a temporary `uint64_t` before being
- // accumulated in `active_delta`, and this intermediate result must not be
- // negative.
- if (user() < baseline.user())
- return -1;
- double active_delta = user() - baseline.user();
- if (nice() < baseline.nice())
- return -1;
- active_delta += nice() - baseline.nice();
- if (system() < baseline.system())
- return -1;
- active_delta += system() - baseline.system();
- if (idle() < baseline.idle())
- return -1;
- uint64_t idle_delta = idle() - baseline.idle();
- // iowait() is unreliable, according to the Linux kernel documentation at
- // https://www.kernel.org/doc/Documentation/filesystems/proc.txt.
- if (irq() < baseline.irq())
- return -1;
- active_delta += irq() - baseline.irq();
- if (softirq() < baseline.softirq())
- return -1;
- active_delta += softirq() - baseline.softirq();
- if (steal() < baseline.steal())
- return -1;
- active_delta += steal() - baseline.steal();
- // guest() and guest_nice() are included in user(). Full analysis in
- // https://unix.stackexchange.com/a/303224/
- double total_delta = active_delta + idle_delta;
- if (total_delta == 0) {
- // The two snapshots represent the same point in time, so the time interval
- // between the two snapshots is empty.
- return -1;
- }
- return active_delta / total_delta;
- }
- } // namespace device
|