xref: /aosp_15_r20/system/extras/simpleperf/utils.h (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
1*288bf522SAndroid Build Coastguard Worker /*
2*288bf522SAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*288bf522SAndroid Build Coastguard Worker  *
4*288bf522SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*288bf522SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*288bf522SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*288bf522SAndroid Build Coastguard Worker  *
8*288bf522SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*288bf522SAndroid Build Coastguard Worker  *
10*288bf522SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*288bf522SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*288bf522SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*288bf522SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*288bf522SAndroid Build Coastguard Worker  * limitations under the License.
15*288bf522SAndroid Build Coastguard Worker  */
16*288bf522SAndroid Build Coastguard Worker 
17*288bf522SAndroid Build Coastguard Worker #ifndef SIMPLE_PERF_UTILS_H_
18*288bf522SAndroid Build Coastguard Worker #define SIMPLE_PERF_UTILS_H_
19*288bf522SAndroid Build Coastguard Worker 
20*288bf522SAndroid Build Coastguard Worker #include <stddef.h>
21*288bf522SAndroid Build Coastguard Worker #include <stdio.h>
22*288bf522SAndroid Build Coastguard Worker #include <time.h>
23*288bf522SAndroid Build Coastguard Worker 
24*288bf522SAndroid Build Coastguard Worker #include <fstream>
25*288bf522SAndroid Build Coastguard Worker #include <functional>
26*288bf522SAndroid Build Coastguard Worker #include <optional>
27*288bf522SAndroid Build Coastguard Worker #include <set>
28*288bf522SAndroid Build Coastguard Worker #include <string>
29*288bf522SAndroid Build Coastguard Worker #include <vector>
30*288bf522SAndroid Build Coastguard Worker 
31*288bf522SAndroid Build Coastguard Worker #include <android-base/logging.h>
32*288bf522SAndroid Build Coastguard Worker #include <android-base/macros.h>
33*288bf522SAndroid Build Coastguard Worker #include <android-base/parseint.h>
34*288bf522SAndroid Build Coastguard Worker #include <android-base/strings.h>
35*288bf522SAndroid Build Coastguard Worker #include <android-base/unique_fd.h>
36*288bf522SAndroid Build Coastguard Worker #include <ziparchive/zip_archive.h>
37*288bf522SAndroid Build Coastguard Worker 
38*288bf522SAndroid Build Coastguard Worker namespace simpleperf {
39*288bf522SAndroid Build Coastguard Worker 
40*288bf522SAndroid Build Coastguard Worker static constexpr size_t kKilobyte = 1024;
41*288bf522SAndroid Build Coastguard Worker static constexpr size_t kMegabyte = 1024 * kKilobyte;
42*288bf522SAndroid Build Coastguard Worker static constexpr uint64_t kGigabyte = 1024 * kMegabyte;
43*288bf522SAndroid Build Coastguard Worker 
AlignDown(uint64_t value,uint64_t alignment)44*288bf522SAndroid Build Coastguard Worker static inline uint64_t AlignDown(uint64_t value, uint64_t alignment) {
45*288bf522SAndroid Build Coastguard Worker   return value & ~(alignment - 1);
46*288bf522SAndroid Build Coastguard Worker }
47*288bf522SAndroid Build Coastguard Worker 
Align(uint64_t value,uint64_t alignment)48*288bf522SAndroid Build Coastguard Worker static inline uint64_t Align(uint64_t value, uint64_t alignment) {
49*288bf522SAndroid Build Coastguard Worker   return AlignDown(value + alignment - 1, alignment);
50*288bf522SAndroid Build Coastguard Worker }
51*288bf522SAndroid Build Coastguard Worker 
52*288bf522SAndroid Build Coastguard Worker #ifdef _WIN32
53*288bf522SAndroid Build Coastguard Worker #define CLOSE_ON_EXEC_MODE ""
54*288bf522SAndroid Build Coastguard Worker #define OS_PATH_SEPARATOR '\\'
55*288bf522SAndroid Build Coastguard Worker #else
56*288bf522SAndroid Build Coastguard Worker #define CLOSE_ON_EXEC_MODE "e"
57*288bf522SAndroid Build Coastguard Worker #define OS_PATH_SEPARATOR '/'
58*288bf522SAndroid Build Coastguard Worker #endif
59*288bf522SAndroid Build Coastguard Worker 
60*288bf522SAndroid Build Coastguard Worker // OneTimeAllocator is used to allocate memory many times and free only once at the end.
61*288bf522SAndroid Build Coastguard Worker // It reduces the cost to free each allocated memory.
62*288bf522SAndroid Build Coastguard Worker class OneTimeFreeAllocator {
63*288bf522SAndroid Build Coastguard Worker  public:
64*288bf522SAndroid Build Coastguard Worker   explicit OneTimeFreeAllocator(size_t unit_size = 8192u)
unit_size_(unit_size)65*288bf522SAndroid Build Coastguard Worker       : unit_size_(unit_size), cur_(nullptr), end_(nullptr) {}
66*288bf522SAndroid Build Coastguard Worker 
~OneTimeFreeAllocator()67*288bf522SAndroid Build Coastguard Worker   ~OneTimeFreeAllocator() { Clear(); }
68*288bf522SAndroid Build Coastguard Worker 
69*288bf522SAndroid Build Coastguard Worker   void Clear();
70*288bf522SAndroid Build Coastguard Worker   const char* AllocateString(std::string_view s);
71*288bf522SAndroid Build Coastguard Worker 
72*288bf522SAndroid Build Coastguard Worker  private:
73*288bf522SAndroid Build Coastguard Worker   const size_t unit_size_;
74*288bf522SAndroid Build Coastguard Worker   std::vector<char*> v_;
75*288bf522SAndroid Build Coastguard Worker   char* cur_;
76*288bf522SAndroid Build Coastguard Worker   char* end_;
77*288bf522SAndroid Build Coastguard Worker };
78*288bf522SAndroid Build Coastguard Worker 
79*288bf522SAndroid Build Coastguard Worker class LineReader {
80*288bf522SAndroid Build Coastguard Worker  public:
LineReader(std::string_view file_path)81*288bf522SAndroid Build Coastguard Worker   explicit LineReader(std::string_view file_path) : ifs_(std::string(file_path).c_str()) {}
82*288bf522SAndroid Build Coastguard Worker   // Return true if open file successfully.
Ok()83*288bf522SAndroid Build Coastguard Worker   bool Ok() const { return ifs_.good(); }
84*288bf522SAndroid Build Coastguard Worker   // If available, return next line content with new line, otherwise return nullptr.
ReadLine()85*288bf522SAndroid Build Coastguard Worker   std::string* ReadLine() { return (std::getline(ifs_, buf_)) ? &buf_ : nullptr; }
86*288bf522SAndroid Build Coastguard Worker 
87*288bf522SAndroid Build Coastguard Worker  private:
88*288bf522SAndroid Build Coastguard Worker   std::ifstream ifs_;
89*288bf522SAndroid Build Coastguard Worker   std::string buf_;
90*288bf522SAndroid Build Coastguard Worker };
91*288bf522SAndroid Build Coastguard Worker 
92*288bf522SAndroid Build Coastguard Worker class FileHelper {
93*288bf522SAndroid Build Coastguard Worker  public:
94*288bf522SAndroid Build Coastguard Worker   static android::base::unique_fd OpenReadOnly(const std::string& filename);
95*288bf522SAndroid Build Coastguard Worker   static android::base::unique_fd OpenWriteOnly(const std::string& filename);
96*288bf522SAndroid Build Coastguard Worker };
97*288bf522SAndroid Build Coastguard Worker 
98*288bf522SAndroid Build Coastguard Worker class ArchiveHelper {
99*288bf522SAndroid Build Coastguard Worker  public:
100*288bf522SAndroid Build Coastguard Worker   static std::unique_ptr<ArchiveHelper> CreateInstance(const std::string& filename);
101*288bf522SAndroid Build Coastguard Worker   ~ArchiveHelper();
102*288bf522SAndroid Build Coastguard Worker   // Iterate each entry in the zip file. Break the iteration when callback returns false.
103*288bf522SAndroid Build Coastguard Worker   bool IterateEntries(const std::function<bool(ZipEntry&, const std::string&)>& callback);
104*288bf522SAndroid Build Coastguard Worker   bool FindEntry(const std::string& name, ZipEntry* entry);
105*288bf522SAndroid Build Coastguard Worker   bool GetEntryData(ZipEntry& entry, std::vector<uint8_t>* data);
106*288bf522SAndroid Build Coastguard Worker   int GetFd();
107*288bf522SAndroid Build Coastguard Worker 
108*288bf522SAndroid Build Coastguard Worker  private:
ArchiveHelper(ZipArchiveHandle handle,const std::string & filename)109*288bf522SAndroid Build Coastguard Worker   ArchiveHelper(ZipArchiveHandle handle, const std::string& filename)
110*288bf522SAndroid Build Coastguard Worker       : handle_(handle), filename_(filename) {}
111*288bf522SAndroid Build Coastguard Worker 
112*288bf522SAndroid Build Coastguard Worker   ZipArchiveHandle handle_;
113*288bf522SAndroid Build Coastguard Worker   std::string filename_;
114*288bf522SAndroid Build Coastguard Worker 
115*288bf522SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(ArchiveHelper);
116*288bf522SAndroid Build Coastguard Worker };
117*288bf522SAndroid Build Coastguard Worker 
118*288bf522SAndroid Build Coastguard Worker template <class T>
MoveFromBinaryFormat(T & data,const char * & p)119*288bf522SAndroid Build Coastguard Worker void MoveFromBinaryFormat(T& data, const char*& p) {
120*288bf522SAndroid Build Coastguard Worker   static_assert(std::is_standard_layout<T>::value, "not standard layout");
121*288bf522SAndroid Build Coastguard Worker   memcpy(&data, p, sizeof(T));
122*288bf522SAndroid Build Coastguard Worker   p += sizeof(T);
123*288bf522SAndroid Build Coastguard Worker }
124*288bf522SAndroid Build Coastguard Worker 
125*288bf522SAndroid Build Coastguard Worker template <class T>
MoveFromBinaryFormat(T & data,char * & p)126*288bf522SAndroid Build Coastguard Worker void MoveFromBinaryFormat(T& data, char*& p) {
127*288bf522SAndroid Build Coastguard Worker   static_assert(std::is_standard_layout<T>::value, "not standard layout");
128*288bf522SAndroid Build Coastguard Worker   memcpy(&data, p, sizeof(T));
129*288bf522SAndroid Build Coastguard Worker   p += sizeof(T);
130*288bf522SAndroid Build Coastguard Worker }
131*288bf522SAndroid Build Coastguard Worker 
132*288bf522SAndroid Build Coastguard Worker template <class T>
MoveFromBinaryFormat(T * data_p,size_t n,const char * & p)133*288bf522SAndroid Build Coastguard Worker void MoveFromBinaryFormat(T* data_p, size_t n, const char*& p) {
134*288bf522SAndroid Build Coastguard Worker   static_assert(std::is_standard_layout<T>::value, "not standard layout");
135*288bf522SAndroid Build Coastguard Worker   size_t size = n * sizeof(T);
136*288bf522SAndroid Build Coastguard Worker   memcpy(data_p, p, size);
137*288bf522SAndroid Build Coastguard Worker   p += size;
138*288bf522SAndroid Build Coastguard Worker }
139*288bf522SAndroid Build Coastguard Worker 
140*288bf522SAndroid Build Coastguard Worker template <class T>
MoveToBinaryFormat(const T & data,char * & p)141*288bf522SAndroid Build Coastguard Worker void MoveToBinaryFormat(const T& data, char*& p) {
142*288bf522SAndroid Build Coastguard Worker   static_assert(std::is_standard_layout<T>::value, "not standard layout");
143*288bf522SAndroid Build Coastguard Worker   memcpy(p, &data, sizeof(T));
144*288bf522SAndroid Build Coastguard Worker   p += sizeof(T);
145*288bf522SAndroid Build Coastguard Worker }
146*288bf522SAndroid Build Coastguard Worker 
147*288bf522SAndroid Build Coastguard Worker template <class T>
MoveToBinaryFormat(const T * data_p,size_t n,char * & p)148*288bf522SAndroid Build Coastguard Worker void MoveToBinaryFormat(const T* data_p, size_t n, char*& p) {
149*288bf522SAndroid Build Coastguard Worker   static_assert(std::is_standard_layout<T>::value, "not standard layout");
150*288bf522SAndroid Build Coastguard Worker   size_t size = n * sizeof(T);
151*288bf522SAndroid Build Coastguard Worker   memcpy(p, data_p, size);
152*288bf522SAndroid Build Coastguard Worker   p += size;
153*288bf522SAndroid Build Coastguard Worker }
154*288bf522SAndroid Build Coastguard Worker 
155*288bf522SAndroid Build Coastguard Worker // Read info from binary data.
156*288bf522SAndroid Build Coastguard Worker struct BinaryReader {
157*288bf522SAndroid Build Coastguard Worker  public:
BinaryReaderBinaryReader158*288bf522SAndroid Build Coastguard Worker   BinaryReader(const char* head, size_t size) : head(head), end(head + size), error(false) {}
159*288bf522SAndroid Build Coastguard Worker 
LeftSizeBinaryReader160*288bf522SAndroid Build Coastguard Worker   size_t LeftSize() const { return end - head; }
161*288bf522SAndroid Build Coastguard Worker 
CheckLeftSizeBinaryReader162*288bf522SAndroid Build Coastguard Worker   bool CheckLeftSize(size_t size) {
163*288bf522SAndroid Build Coastguard Worker     if (UNLIKELY(error)) {
164*288bf522SAndroid Build Coastguard Worker       return false;
165*288bf522SAndroid Build Coastguard Worker     }
166*288bf522SAndroid Build Coastguard Worker     if (UNLIKELY(LeftSize() < size)) {
167*288bf522SAndroid Build Coastguard Worker       error = true;
168*288bf522SAndroid Build Coastguard Worker       return false;
169*288bf522SAndroid Build Coastguard Worker     }
170*288bf522SAndroid Build Coastguard Worker     return true;
171*288bf522SAndroid Build Coastguard Worker   }
172*288bf522SAndroid Build Coastguard Worker 
MoveBinaryReader173*288bf522SAndroid Build Coastguard Worker   void Move(size_t size) {
174*288bf522SAndroid Build Coastguard Worker     if (CheckLeftSize(size)) {
175*288bf522SAndroid Build Coastguard Worker       head += size;
176*288bf522SAndroid Build Coastguard Worker     }
177*288bf522SAndroid Build Coastguard Worker   }
178*288bf522SAndroid Build Coastguard Worker 
179*288bf522SAndroid Build Coastguard Worker   template <class T>
ReadBinaryReader180*288bf522SAndroid Build Coastguard Worker   void Read(T& data) {
181*288bf522SAndroid Build Coastguard Worker     static_assert(std::is_standard_layout<T>::value, "not standard layout");
182*288bf522SAndroid Build Coastguard Worker     if (UNLIKELY(error)) {
183*288bf522SAndroid Build Coastguard Worker       return;
184*288bf522SAndroid Build Coastguard Worker     }
185*288bf522SAndroid Build Coastguard Worker     if (UNLIKELY(LeftSize() < sizeof(T))) {
186*288bf522SAndroid Build Coastguard Worker       error = true;
187*288bf522SAndroid Build Coastguard Worker     } else {
188*288bf522SAndroid Build Coastguard Worker       memcpy(&data, head, sizeof(T));
189*288bf522SAndroid Build Coastguard Worker       head += sizeof(T);
190*288bf522SAndroid Build Coastguard Worker     }
191*288bf522SAndroid Build Coastguard Worker   }
192*288bf522SAndroid Build Coastguard Worker 
193*288bf522SAndroid Build Coastguard Worker   template <class T>
ReadBinaryReader194*288bf522SAndroid Build Coastguard Worker   void Read(T* data_p, size_t n) {
195*288bf522SAndroid Build Coastguard Worker     static_assert(std::is_standard_layout<T>::value, "not standard layout");
196*288bf522SAndroid Build Coastguard Worker     if (UNLIKELY(error)) {
197*288bf522SAndroid Build Coastguard Worker       return;
198*288bf522SAndroid Build Coastguard Worker     }
199*288bf522SAndroid Build Coastguard Worker     size_t size;
200*288bf522SAndroid Build Coastguard Worker     if (UNLIKELY(__builtin_mul_overflow(n, sizeof(T), &size) || LeftSize() < size)) {
201*288bf522SAndroid Build Coastguard Worker       error = true;
202*288bf522SAndroid Build Coastguard Worker     } else {
203*288bf522SAndroid Build Coastguard Worker       memcpy(data_p, head, size);
204*288bf522SAndroid Build Coastguard Worker       head += size;
205*288bf522SAndroid Build Coastguard Worker     }
206*288bf522SAndroid Build Coastguard Worker   }
207*288bf522SAndroid Build Coastguard Worker 
208*288bf522SAndroid Build Coastguard Worker   // Read a string ending with '\0'.
ReadStringBinaryReader209*288bf522SAndroid Build Coastguard Worker   std::string ReadString() {
210*288bf522SAndroid Build Coastguard Worker     if (UNLIKELY(error)) {
211*288bf522SAndroid Build Coastguard Worker       return "";
212*288bf522SAndroid Build Coastguard Worker     }
213*288bf522SAndroid Build Coastguard Worker     std::string result;
214*288bf522SAndroid Build Coastguard Worker     while (head < end && *head != '\0') {
215*288bf522SAndroid Build Coastguard Worker       result.push_back(*head++);
216*288bf522SAndroid Build Coastguard Worker     }
217*288bf522SAndroid Build Coastguard Worker     if (LIKELY(head < end && *head == '\0')) {
218*288bf522SAndroid Build Coastguard Worker       head++;
219*288bf522SAndroid Build Coastguard Worker       return result;
220*288bf522SAndroid Build Coastguard Worker     }
221*288bf522SAndroid Build Coastguard Worker     error = true;
222*288bf522SAndroid Build Coastguard Worker     return "";
223*288bf522SAndroid Build Coastguard Worker   }
224*288bf522SAndroid Build Coastguard Worker 
225*288bf522SAndroid Build Coastguard Worker   const char* head;
226*288bf522SAndroid Build Coastguard Worker   const char* end;
227*288bf522SAndroid Build Coastguard Worker   bool error;
228*288bf522SAndroid Build Coastguard Worker };
229*288bf522SAndroid Build Coastguard Worker 
230*288bf522SAndroid Build Coastguard Worker void PrintIndented(size_t indent, const char* fmt, ...);
231*288bf522SAndroid Build Coastguard Worker void FprintIndented(FILE* fp, size_t indent, const char* fmt, ...);
232*288bf522SAndroid Build Coastguard Worker 
233*288bf522SAndroid Build Coastguard Worker bool IsPowerOfTwo(uint64_t value);
234*288bf522SAndroid Build Coastguard Worker 
235*288bf522SAndroid Build Coastguard Worker std::vector<std::string> GetEntriesInDir(const std::string& dirpath);
236*288bf522SAndroid Build Coastguard Worker std::vector<std::string> GetSubDirs(const std::string& dirpath);
237*288bf522SAndroid Build Coastguard Worker bool IsDir(const std::string& dirpath);
238*288bf522SAndroid Build Coastguard Worker bool IsRegularFile(const std::string& filename);
239*288bf522SAndroid Build Coastguard Worker uint64_t GetFileSize(const std::string& filename);
240*288bf522SAndroid Build Coastguard Worker bool MkdirWithParents(const std::string& path);
241*288bf522SAndroid Build Coastguard Worker 
242*288bf522SAndroid Build Coastguard Worker bool XzDecompress(const std::string& compressed_data, std::string* decompressed_data);
243*288bf522SAndroid Build Coastguard Worker 
244*288bf522SAndroid Build Coastguard Worker bool GetLogSeverity(const std::string& name, android::base::LogSeverity* severity);
245*288bf522SAndroid Build Coastguard Worker std::string GetLogSeverityName();
246*288bf522SAndroid Build Coastguard Worker 
247*288bf522SAndroid Build Coastguard Worker bool IsRoot();
248*288bf522SAndroid Build Coastguard Worker 
249*288bf522SAndroid Build Coastguard Worker size_t GetPageSize();
250*288bf522SAndroid Build Coastguard Worker 
251*288bf522SAndroid Build Coastguard Worker uint64_t ConvertBytesToValue(const char* bytes, uint32_t size);
252*288bf522SAndroid Build Coastguard Worker 
253*288bf522SAndroid Build Coastguard Worker timeval SecondToTimeval(double time_in_sec);
254*288bf522SAndroid Build Coastguard Worker 
255*288bf522SAndroid Build Coastguard Worker std::string GetSimpleperfVersion();
256*288bf522SAndroid Build Coastguard Worker 
257*288bf522SAndroid Build Coastguard Worker std::optional<std::set<int>> GetCpusFromString(const std::string& s);
258*288bf522SAndroid Build Coastguard Worker std::optional<std::set<pid_t>> GetTidsFromString(const std::string& s, bool check_if_exists);
259*288bf522SAndroid Build Coastguard Worker std::optional<std::set<pid_t>> GetPidsFromStrings(const std::vector<std::string>& strs,
260*288bf522SAndroid Build Coastguard Worker                                                   bool check_if_exists,
261*288bf522SAndroid Build Coastguard Worker                                                   bool support_progress_name_regex);
262*288bf522SAndroid Build Coastguard Worker 
263*288bf522SAndroid Build Coastguard Worker template <typename T>
ParseUintVector(const std::string & s)264*288bf522SAndroid Build Coastguard Worker std::optional<std::set<T>> ParseUintVector(const std::string& s) {
265*288bf522SAndroid Build Coastguard Worker   std::set<T> result;
266*288bf522SAndroid Build Coastguard Worker   T value;
267*288bf522SAndroid Build Coastguard Worker   for (const auto& p : android::base::Split(s, ",")) {
268*288bf522SAndroid Build Coastguard Worker     if (!android::base::ParseUint(p.c_str(), &value, std::numeric_limits<T>::max())) {
269*288bf522SAndroid Build Coastguard Worker       LOG(ERROR) << "Invalid Uint '" << p << "' in " << s;
270*288bf522SAndroid Build Coastguard Worker       return std::nullopt;
271*288bf522SAndroid Build Coastguard Worker     }
272*288bf522SAndroid Build Coastguard Worker     result.insert(value);
273*288bf522SAndroid Build Coastguard Worker   }
274*288bf522SAndroid Build Coastguard Worker   return result;
275*288bf522SAndroid Build Coastguard Worker }
276*288bf522SAndroid Build Coastguard Worker 
277*288bf522SAndroid Build Coastguard Worker // from boost::hash_combine
278*288bf522SAndroid Build Coastguard Worker template <typename T>
HashCombine(size_t & seed,const T & val)279*288bf522SAndroid Build Coastguard Worker static inline void HashCombine(size_t& seed, const T& val) {
280*288bf522SAndroid Build Coastguard Worker   seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
281*288bf522SAndroid Build Coastguard Worker }
282*288bf522SAndroid Build Coastguard Worker 
283*288bf522SAndroid Build Coastguard Worker size_t SafeStrlen(const char* s, const char* end);
284*288bf522SAndroid Build Coastguard Worker 
285*288bf522SAndroid Build Coastguard Worker struct OverflowResult {
286*288bf522SAndroid Build Coastguard Worker   bool overflow = false;
287*288bf522SAndroid Build Coastguard Worker   uint64_t value = 0;
288*288bf522SAndroid Build Coastguard Worker };
289*288bf522SAndroid Build Coastguard Worker 
290*288bf522SAndroid Build Coastguard Worker OverflowResult SafeAdd(uint64_t a, uint64_t b);
291*288bf522SAndroid Build Coastguard Worker void OverflowSafeAdd(uint64_t& dest, uint64_t add);
292*288bf522SAndroid Build Coastguard Worker 
293*288bf522SAndroid Build Coastguard Worker std::string ReadableCount(uint64_t count);
294*288bf522SAndroid Build Coastguard Worker std::string ReadableBytes(uint64_t bytes);
295*288bf522SAndroid Build Coastguard Worker 
296*288bf522SAndroid Build Coastguard Worker }  // namespace simpleperf
297*288bf522SAndroid Build Coastguard Worker 
298*288bf522SAndroid Build Coastguard Worker #endif  // SIMPLE_PERF_UTILS_H_
299