xref: /aosp_15_r20/external/cronet/base/android/thread_instruction_count.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2022 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_ANDROID_THREAD_INSTRUCTION_COUNT_H_
6*6777b538SAndroid Build Coastguard Worker #define BASE_ANDROID_THREAD_INSTRUCTION_COUNT_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h"
11*6777b538SAndroid Build Coastguard Worker 
12*6777b538SAndroid Build Coastguard Worker namespace base {
13*6777b538SAndroid Build Coastguard Worker namespace android {
14*6777b538SAndroid Build Coastguard Worker 
15*6777b538SAndroid Build Coastguard Worker // Represents the number of instructions that were retired between two samples
16*6777b538SAndroid Build Coastguard Worker // of a thread's performance counters.
17*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT ThreadInstructionDelta {
18*6777b538SAndroid Build Coastguard Worker  public:
ThreadInstructionDelta()19*6777b538SAndroid Build Coastguard Worker   constexpr ThreadInstructionDelta() : delta_(0) {}
ThreadInstructionDelta(int64_t delta)20*6777b538SAndroid Build Coastguard Worker   explicit constexpr ThreadInstructionDelta(int64_t delta) : delta_(delta) {}
21*6777b538SAndroid Build Coastguard Worker 
ToInternalValue()22*6777b538SAndroid Build Coastguard Worker   constexpr int64_t ToInternalValue() const { return delta_; }
23*6777b538SAndroid Build Coastguard Worker 
24*6777b538SAndroid Build Coastguard Worker  private:
25*6777b538SAndroid Build Coastguard Worker   int64_t delta_;
26*6777b538SAndroid Build Coastguard Worker };
27*6777b538SAndroid Build Coastguard Worker 
28*6777b538SAndroid Build Coastguard Worker // Helper class for reading the current count of instructions retired for the
29*6777b538SAndroid Build Coastguard Worker // current thread via ThreadInstructionCount::Now(). Does *not* count
30*6777b538SAndroid Build Coastguard Worker // instructions retired while running in the kernel.
31*6777b538SAndroid Build Coastguard Worker //
32*6777b538SAndroid Build Coastguard Worker // Limitations:
33*6777b538SAndroid Build Coastguard Worker // * Crashes when used in sandboxed process
34*6777b538SAndroid Build Coastguard Worker // * Works on a userdebug build of Android 12, kernel 4.19. May require extra
35*6777b538SAndroid Build Coastguard Worker //   effort to allow on later Android releases and kernel versions.
36*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT ThreadInstructionCount {
37*6777b538SAndroid Build Coastguard Worker  public:
38*6777b538SAndroid Build Coastguard Worker   // Returns true if the platform supports hardware retired instruction
39*6777b538SAndroid Build Coastguard Worker   // counters. May crash in sandboxed processes.
40*6777b538SAndroid Build Coastguard Worker   static bool IsSupported();
41*6777b538SAndroid Build Coastguard Worker 
42*6777b538SAndroid Build Coastguard Worker   // Returns the number of retired instructions relative to some epoch count,
43*6777b538SAndroid Build Coastguard Worker   // or 0 if getting the current instruction count failed / is disabled.
44*6777b538SAndroid Build Coastguard Worker   static ThreadInstructionCount Now();
45*6777b538SAndroid Build Coastguard Worker 
46*6777b538SAndroid Build Coastguard Worker   explicit constexpr ThreadInstructionCount(uint64_t value = 0)
value_(value)47*6777b538SAndroid Build Coastguard Worker       : value_(value) {}
48*6777b538SAndroid Build Coastguard Worker 
49*6777b538SAndroid Build Coastguard Worker   constexpr ThreadInstructionDelta operator-(
50*6777b538SAndroid Build Coastguard Worker       ThreadInstructionCount other) const {
51*6777b538SAndroid Build Coastguard Worker     return ThreadInstructionDelta(static_cast<int64_t>(value_ - other.value_));
52*6777b538SAndroid Build Coastguard Worker   }
53*6777b538SAndroid Build Coastguard Worker 
ToInternalValue()54*6777b538SAndroid Build Coastguard Worker   constexpr uint64_t ToInternalValue() const { return value_; }
55*6777b538SAndroid Build Coastguard Worker 
56*6777b538SAndroid Build Coastguard Worker  private:
57*6777b538SAndroid Build Coastguard Worker   uint64_t value_;
58*6777b538SAndroid Build Coastguard Worker };
59*6777b538SAndroid Build Coastguard Worker 
60*6777b538SAndroid Build Coastguard Worker }  // namespace android
61*6777b538SAndroid Build Coastguard Worker }  // namespace base
62*6777b538SAndroid Build Coastguard Worker 
63*6777b538SAndroid Build Coastguard Worker #endif  // BASE_ANDROID_THREAD_INSTRUCTION_COUNT_H_
64