blob: 10de9324282b76fc99421b4af6326aad6fbf919f [file] [log] [blame]
Yabin Cui67d3abd2015-04-16 15:26:31 -07001/*
2 * Copyright (C) 2015 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 SIMPLE_PERF_UTILS_H_
18#define SIMPLE_PERF_UTILS_H_
19
20#include <stddef.h>
Thiébaud Weksteene7e750e2020-11-19 15:07:46 +010021#include <stdio.h>
Yabin Cui3e4c5952016-07-26 15:03:27 -070022#include <time.h>
Yabin Cuicc2e59e2015-08-21 14:23:43 -070023
Yabin Cui40eef9e2021-04-13 13:08:31 -070024#include <fstream>
Yabin Cui2a53ff32018-05-21 17:37:00 -070025#include <functional>
Yabin Cuie3ca9982020-10-16 13:16:26 -070026#include <optional>
Namhyung Kima5f1d422019-12-17 17:15:02 +090027#include <set>
Yabin Cui323e9452015-04-20 18:07:17 -070028#include <string>
Yabin Cui9759e1b2015-04-28 15:54:13 -070029#include <vector>
Yabin Cui67d3abd2015-04-16 15:26:31 -070030
Yabin Cui8f680f62016-03-18 18:47:43 -070031#include <android-base/logging.h>
Yabin Cuib1a885b2016-02-14 19:18:02 -080032#include <android-base/macros.h>
Yabin Cuia89a3742021-02-11 13:14:54 -080033#include <android-base/parseint.h>
34#include <android-base/strings.h>
Yabin Cui2a53ff32018-05-21 17:37:00 -070035#include <android-base/unique_fd.h>
Yabin Cuibe7ec662016-03-02 13:56:28 -080036#include <ziparchive/zip_archive.h>
Yabin Cuib1a885b2016-02-14 19:18:02 -080037
Yabin Cuifaa7b922021-01-11 17:35:57 -080038namespace simpleperf {
39
Evgeny Eltsin91dbae02020-08-27 15:46:09 +020040static inline uint64_t AlignDown(uint64_t value, uint64_t alignment) {
41 return value & ~(alignment - 1);
42}
43
Yabin Cuia7a0e502016-06-15 11:49:23 -070044static inline uint64_t Align(uint64_t value, uint64_t alignment) {
Evgeny Eltsin91dbae02020-08-27 15:46:09 +020045 return AlignDown(value + alignment - 1, alignment);
Yabin Cuia7a0e502016-06-15 11:49:23 -070046}
Yabin Cui67d3abd2015-04-16 15:26:31 -070047
Yabin Cuiffaa9122016-01-15 15:25:48 -080048#ifdef _WIN32
49#define CLOSE_ON_EXEC_MODE ""
Yabin Cui1b9b1c12018-10-29 14:23:48 -070050#define OS_PATH_SEPARATOR '\\'
Yabin Cuiffaa9122016-01-15 15:25:48 -080051#else
52#define CLOSE_ON_EXEC_MODE "e"
Yabin Cui1b9b1c12018-10-29 14:23:48 -070053#define OS_PATH_SEPARATOR '/'
Yabin Cuiffaa9122016-01-15 15:25:48 -080054#endif
Yabin Cui621a5332015-06-15 16:17:20 -070055
Yabin Cuicc2e59e2015-08-21 14:23:43 -070056// OneTimeAllocator is used to allocate memory many times and free only once at the end.
57// It reduces the cost to free each allocated memory.
58class OneTimeFreeAllocator {
59 public:
Chih-Hung Hsieh5674ed82016-07-12 11:35:16 -070060 explicit OneTimeFreeAllocator(size_t unit_size = 8192u)
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020061 : unit_size_(unit_size), cur_(nullptr), end_(nullptr) {}
Yabin Cuicc2e59e2015-08-21 14:23:43 -070062
Thiébaud Weksteen4848ee02020-10-23 16:06:59 +020063 ~OneTimeFreeAllocator() { Clear(); }
Yabin Cuicc2e59e2015-08-21 14:23:43 -070064
65 void Clear();
Martin Stjernholm7c27cc22018-11-28 00:46:00 +000066 const char* AllocateString(std::string_view s);
Yabin Cuicc2e59e2015-08-21 14:23:43 -070067
68 private:
69 const size_t unit_size_;
70 std::vector<char*> v_;
71 char* cur_;
72 char* end_;
73};
74
Thiébaud Weksteene7e750e2020-11-19 15:07:46 +010075class LineReader {
76 public:
Yabin Cui40eef9e2021-04-13 13:08:31 -070077 explicit LineReader(std::string_view file_path) : ifs_(file_path) {}
78 // Return true if open file successfully.
79 bool Ok() const { return ifs_.good(); }
80 // If available, return next line content with new line, otherwise return nullptr.
81 std::string* ReadLine() { return (std::getline(ifs_, buf_)) ? &buf_ : nullptr; }
Thiébaud Weksteene7e750e2020-11-19 15:07:46 +010082
83 private:
Yabin Cui40eef9e2021-04-13 13:08:31 -070084 std::ifstream ifs_;
85 std::string buf_;
Thiébaud Weksteene7e750e2020-11-19 15:07:46 +010086};
87
Yabin Cuib1a885b2016-02-14 19:18:02 -080088class FileHelper {
89 public:
Yabin Cui2a53ff32018-05-21 17:37:00 -070090 static android::base::unique_fd OpenReadOnly(const std::string& filename);
91 static android::base::unique_fd OpenWriteOnly(const std::string& filename);
Yabin Cuib1a885b2016-02-14 19:18:02 -080092};
93
Yabin Cuibe7ec662016-03-02 13:56:28 -080094class ArchiveHelper {
95 public:
Yabin Cui2a53ff32018-05-21 17:37:00 -070096 static std::unique_ptr<ArchiveHelper> CreateInstance(const std::string& filename);
Yabin Cuibe7ec662016-03-02 13:56:28 -080097 ~ArchiveHelper();
Yabin Cui2a53ff32018-05-21 17:37:00 -070098 // Iterate each entry in the zip file. Break the iteration when callback returns false.
99 bool IterateEntries(const std::function<bool(ZipEntry&, const std::string&)>& callback);
100 bool FindEntry(const std::string& name, ZipEntry* entry);
101 bool GetEntryData(ZipEntry& entry, std::vector<uint8_t>* data);
102 int GetFd();
Yabin Cuibe7ec662016-03-02 13:56:28 -0800103
104 private:
Yabin Cui2a53ff32018-05-21 17:37:00 -0700105 ArchiveHelper(ZipArchiveHandle handle, const std::string& filename)
106 : handle_(handle), filename_(filename) {}
107
Yabin Cuibe7ec662016-03-02 13:56:28 -0800108 ZipArchiveHandle handle_;
Yabin Cui2a53ff32018-05-21 17:37:00 -0700109 std::string filename_;
Yabin Cuibe7ec662016-03-02 13:56:28 -0800110
111 DISALLOW_COPY_AND_ASSIGN(ArchiveHelper);
112};
113
Yabin Cuid713f952015-06-23 18:50:36 -0700114template <class T>
115void MoveFromBinaryFormat(T& data, const char*& p) {
Yabin Cui2597ef02016-10-19 11:28:48 -0700116 static_assert(std::is_standard_layout<T>::value, "not standard layout");
Yabin Cuic24dd762016-11-10 15:25:15 -0800117 memcpy(&data, p, sizeof(T));
Yabin Cuid713f952015-06-23 18:50:36 -0700118 p += sizeof(T);
119}
120
Yabin Cui2597ef02016-10-19 11:28:48 -0700121template <class T>
Yabin Cui3d4aa262017-11-01 15:58:55 -0700122void MoveFromBinaryFormat(T& data, char*& p) {
123 static_assert(std::is_standard_layout<T>::value, "not standard layout");
124 memcpy(&data, p, sizeof(T));
125 p += sizeof(T);
126}
127
128template <class T>
Yabin Cui2597ef02016-10-19 11:28:48 -0700129void MoveFromBinaryFormat(T* data_p, size_t n, const char*& p) {
130 static_assert(std::is_standard_layout<T>::value, "not standard layout");
131 size_t size = n * sizeof(T);
132 memcpy(data_p, p, size);
133 p += size;
134}
135
136template <class T>
137void MoveToBinaryFormat(const T& data, char*& p) {
138 static_assert(std::is_standard_layout<T>::value, "not standard layout");
Yabin Cuic24dd762016-11-10 15:25:15 -0800139 memcpy(p, &data, sizeof(T));
Yabin Cui2597ef02016-10-19 11:28:48 -0700140 p += sizeof(T);
141}
142
143template <class T>
144void MoveToBinaryFormat(const T* data_p, size_t n, char*& p) {
145 static_assert(std::is_standard_layout<T>::value, "not standard layout");
146 size_t size = n * sizeof(T);
147 memcpy(p, data_p, size);
148 p += size;
149}
150
Yabin Cui7d59bb42015-05-04 20:27:57 -0700151void PrintIndented(size_t indent, const char* fmt, ...);
Yabin Cui767dd172016-06-02 21:02:43 -0700152void FprintIndented(FILE* fp, size_t indent, const char* fmt, ...);
Yabin Cui7d59bb42015-05-04 20:27:57 -0700153
Yabin Cui9759e1b2015-04-28 15:54:13 -0700154bool IsPowerOfTwo(uint64_t value);
155
Yabin Cui07865862016-08-22 13:39:19 -0700156std::vector<std::string> GetEntriesInDir(const std::string& dirpath);
157std::vector<std::string> GetSubDirs(const std::string& dirpath);
Yabin Cuib032de72015-06-17 21:15:09 -0700158bool IsDir(const std::string& dirpath);
Yabin Cui797116b2015-12-08 17:43:15 -0800159bool IsRegularFile(const std::string& filename);
Yabin Cuib1a885b2016-02-14 19:18:02 -0800160uint64_t GetFileSize(const std::string& filename);
Yabin Cuibe7ec662016-03-02 13:56:28 -0800161bool MkdirWithParents(const std::string& path);
Yabin Cui323e9452015-04-20 18:07:17 -0700162
Yabin Cui05400532016-03-17 21:18:53 -0700163bool XzDecompress(const std::string& compressed_data, std::string* decompressed_data);
164
Yabin Cui8f680f62016-03-18 18:47:43 -0700165bool GetLogSeverity(const std::string& name, android::base::LogSeverity* severity);
Yabin Cui750b3732017-12-18 17:46:36 -0800166std::string GetLogSeverityName();
Yabin Cui8f680f62016-03-18 18:47:43 -0700167
Yabin Cui56335862016-04-18 13:43:20 -0700168bool IsRoot();
169
Yabin Cui4f41df62016-06-01 17:29:06 -0700170size_t GetPageSize();
171
172uint64_t ConvertBytesToValue(const char* bytes, uint32_t size);
173
Yabin Cui3e4c5952016-07-26 15:03:27 -0700174timeval SecondToTimeval(double time_in_sec);
175
Yabin Cuidf6333c2017-05-03 16:34:02 -0700176std::string GetSimpleperfVersion();
177
Yabin Cuie3ca9982020-10-16 13:16:26 -0700178std::optional<std::set<int>> GetCpusFromString(const std::string& s);
179std::optional<std::set<pid_t>> GetTidsFromString(const std::string& s, bool check_if_exists);
Namhyung Kima5f1d422019-12-17 17:15:02 +0900180
Yabin Cuia89a3742021-02-11 13:14:54 -0800181template <typename T>
182std::optional<std::set<T>> ParseUintVector(const std::string& s) {
183 std::set<T> result;
184 T value;
185 for (const auto& p : android::base::Split(s, ",")) {
186 if (!android::base::ParseUint(p.c_str(), &value, std::numeric_limits<T>::max())) {
187 LOG(ERROR) << "Invalid Uint '" << p << "' in " << s;
188 return std::nullopt;
189 }
190 result.insert(value);
191 }
192 return result;
193}
194
Yabin Cuifad7bbe2019-09-18 16:05:51 -0700195// from boost::hash_combine
196template <typename T>
Yabin Cuifaa7b922021-01-11 17:35:57 -0800197static inline void HashCombine(size_t& seed, const T& val) {
Yabin Cuifad7bbe2019-09-18 16:05:51 -0700198 seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
199}
200
Yabin Cui1cb85802021-11-12 17:56:57 -0800201size_t SafeStrlen(const char* s, const char* end);
202
Yabin Cuifaa7b922021-01-11 17:35:57 -0800203} // namespace simpleperf
Yabin Cuifad7bbe2019-09-18 16:05:51 -0700204
Yabin Cui67d3abd2015-04-16 15:26:31 -0700205#endif // SIMPLE_PERF_UTILS_H_