1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef INCLUDE_PERFETTO_TRACING_CORE_FLUSH_FLAGS_H_ 18 #define INCLUDE_PERFETTO_TRACING_CORE_FLUSH_FLAGS_H_ 19 20 #include <stddef.h> 21 #include <stdint.h> 22 23 namespace perfetto { 24 25 // This class is a wrapper around the uint64_t flags that are sent across the 26 // tracing protocol whenenver a flush occurs. It helps determining the reason 27 // and initiator of the flush. 28 // NOTE: the values here are part of the tracing protocol ABI. Do not renumber. 29 class FlushFlags { 30 public: 31 enum class Initiator : uint64_t { 32 // DO NOT RENUMBER, ABI. 33 kUnknown = 0, 34 kTraced = 1, 35 kPerfettoCmd = 2, 36 kConsumerSdk = 3, 37 kMax, 38 }; 39 40 enum class Reason : uint64_t { 41 // DO NOT RENUMBER, ABI. 42 kUnknown = 0, 43 kPeriodic = 1, 44 kTraceStop = 2, 45 kTraceClone = 3, 46 kExplicit = 4, 47 kMax, 48 }; 49 50 enum class CloneTarget : uint64_t { 51 // DO NOT RENUMBER, ABI. 52 kUnknown = 0, 53 kBugreport = 1, 54 kMax, 55 }; 56 flags_(flags)57 explicit FlushFlags(uint64_t flags = 0) : flags_(flags) {} 58 FlushFlags(Initiator i, Reason r, CloneTarget c = CloneTarget::kUnknown) 59 : flags_((static_cast<uint64_t>(i) << kInitiatorShift) | 60 (static_cast<uint64_t>(r) << kReasonShift) | 61 (static_cast<uint64_t>(c) << kCloneTargetShift)) {} 62 63 bool operator==(const FlushFlags& o) const { return flags_ == o.flags_; } 64 bool operator!=(const FlushFlags& o) const { return !(*this == o); } 65 initiator()66 Initiator initiator() const { 67 // Due to version mismatch we might see a value from the future that we 68 // didn't know yet. If that happens, short ciruit to kUnknown. 69 static_assert( 70 uint64_t(Initiator::kMax) - 1 <= (kInitiatorMask >> kInitiatorShift), 71 "enum out of range"); 72 const uint64_t value = (flags_ & kInitiatorMask) >> kInitiatorShift; 73 return value < uint64_t(Initiator::kMax) ? Initiator(value) 74 : Initiator::kUnknown; 75 } 76 reason()77 Reason reason() const { 78 static_assert(uint64_t(Reason::kMax) - 1 <= (kReasonMask >> kReasonShift), 79 "enum out of range"); 80 const uint64_t value = (flags_ & kReasonMask) >> kReasonShift; 81 return value < uint64_t(Reason::kMax) ? Reason(value) : Reason::kUnknown; 82 } 83 clone_target()84 CloneTarget clone_target() const { 85 static_assert(uint64_t(CloneTarget::kMax) - 1 <= 86 (kCloneTargetMask >> kCloneTargetShift), 87 "enum out of range"); 88 const uint64_t value = (flags_ & kCloneTargetMask) >> kCloneTargetShift; 89 return value < uint64_t(CloneTarget::kMax) ? CloneTarget(value) 90 : CloneTarget::kUnknown; 91 } 92 flags()93 uint64_t flags() const { return flags_; } 94 95 private: 96 // DO NOT CHANGE, ABI. 97 static constexpr uint64_t kReasonMask = 0xF; 98 static constexpr uint64_t kReasonShift = 0; 99 static constexpr uint64_t kInitiatorMask = 0xF0; 100 static constexpr uint64_t kInitiatorShift = 4; 101 static constexpr uint64_t kCloneTargetMask = 0xF00; 102 static constexpr uint64_t kCloneTargetShift = 8; 103 104 uint64_t flags_ = 0; 105 }; 106 107 } // namespace perfetto 108 109 #endif // INCLUDE_PERFETTO_TRACING_CORE_FLUSH_FLAGS_H_ 110