1 /* 2 * Copyright (C) 2019 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 SRC_TRACE_PROCESSOR_FTRACE_UTILS_H_ 18 #define SRC_TRACE_PROCESSOR_FTRACE_UTILS_H_ 19 20 #include <stddef.h> 21 #include <array> 22 23 #include "perfetto/base/logging.h" 24 #include "perfetto/base/string_view.h" 25 #include "perfetto/base/string_writer.h" 26 27 namespace perfetto { 28 namespace trace_processor { 29 namespace ftrace_utils { 30 31 // A strongly typed representation of the TaskState enum given in sched_switch 32 // events. 33 class TaskState { 34 public: 35 using TaskStateStr = std::array<char, 4>; 36 37 // The ordering and values of these fields comes from the kernel in the file 38 // https://android.googlesource.com/kernel/msm.git/+/android-msm-wahoo-4.4-pie-qpr1/include/linux/sched.h#212 39 enum Atom : uint16_t { 40 kRunnable = 0, 41 kInterruptibleSleep = 1, 42 kUninterruptibleSleep = 2, 43 kStopped = 4, 44 kTraced = 8, 45 kExitDead = 16, 46 kExitZombie = 32, 47 kTaskDead = 64, 48 kWakeKill = 128, 49 kWaking = 256, 50 kParked = 512, 51 kNoLoad = 1024, 52 53 // kMaxState is used by sched switch to show a task was kernel preempted. 54 // The difficult thing is that in newer kernels a task_new state is added 55 // and kMaxState increases to 4096. Without the kernel version and the 56 // mapping of this to the correct version of this enum we cannot be 57 // accurate. Since task_new is rare we ignore it for now. 58 kTaskNewOrMaxState = 2048, 59 kMaxState = 4096, 60 kValid = 0x8000, 61 }; 62 63 TaskState() = default; TaskState(uint16_t raw_state)64 explicit TaskState(uint16_t raw_state) : state_(raw_state | kValid) {} 65 explicit TaskState(const char* state_str); 66 67 // Returns if this TaskState has a valid representation. is_valid()68 bool is_valid() const { return state_ & kValid; } 69 70 // Returns the string representation of this (valid) TaskState. This array 71 // is null terminated. 72 // Note: This function CHECKs that |is_valid()| is true. 73 TaskStateStr ToString() const; 74 75 // Returns the raw state this class was created from. raw_state()76 uint16_t raw_state() const { 77 PERFETTO_DCHECK(is_valid()); 78 return state_ & ~kValid; 79 } 80 81 // Returns if this TaskState is runnable. is_runnable()82 bool is_runnable() const { 83 return ((state_ & (kMaxState - 1)) == 0) || 84 ((state_ & (kTaskNewOrMaxState - 1)) == 0); 85 } 86 87 // Returns whether kernel preemption caused the exit state. is_kernel_preempt()88 bool is_kernel_preempt() const { 89 return state_ & kTaskNewOrMaxState || state_ & kMaxState; 90 } 91 92 private: 93 uint16_t state_ = 0; 94 }; 95 96 void FormatSystracePrefix(int64_t timestamp, 97 uint32_t cpu, 98 uint32_t pid, 99 uint32_t tgid, 100 base::StringView name, 101 base::StringWriter* writer); 102 103 } // namespace ftrace_utils 104 } // namespace trace_processor 105 } // namespace perfetto 106 107 #endif // SRC_TRACE_PROCESSOR_FTRACE_UTILS_H_ 108