OSDN Git Service

Merge "Simpleperf: adjust default mmap_pages used when recording."
[android-x86/system-extras.git] / simpleperf / utils.cpp
1 /*
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 #include "utils.h"
18
19 #include <dirent.h>
20 #include <errno.h>
21 #include <stdarg.h>
22 #include <stdio.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25
26 #include <algorithm>
27 #include <string>
28
29 #include <android-base/logging.h>
30
31 void OneTimeFreeAllocator::Clear() {
32   for (auto& p : v_) {
33     delete[] p;
34   }
35   v_.clear();
36   cur_ = nullptr;
37   end_ = nullptr;
38 }
39
40 const char* OneTimeFreeAllocator::AllocateString(const std::string& s) {
41   size_t size = s.size() + 1;
42   if (cur_ + size > end_) {
43     size_t alloc_size = std::max(size, unit_size_);
44     char* p = new char[alloc_size];
45     v_.push_back(p);
46     cur_ = p;
47     end_ = p + alloc_size;
48   }
49   strcpy(cur_, s.c_str());
50   const char* result = cur_;
51   cur_ += size;
52   return result;
53 }
54
55 void PrintIndented(size_t indent, const char* fmt, ...) {
56   va_list ap;
57   va_start(ap, fmt);
58   printf("%*s", static_cast<int>(indent * 2), "");
59   vprintf(fmt, ap);
60   va_end(ap);
61 }
62
63 bool IsPowerOfTwo(uint64_t value) {
64   return (value != 0 && ((value & (value - 1)) == 0));
65 }
66
67 void GetEntriesInDir(const std::string& dirpath, std::vector<std::string>* files,
68                      std::vector<std::string>* subdirs) {
69   if (files != nullptr) {
70     files->clear();
71   }
72   if (subdirs != nullptr) {
73     subdirs->clear();
74   }
75   DIR* dir = opendir(dirpath.c_str());
76   if (dir == nullptr) {
77     PLOG(DEBUG) << "can't open dir " << dirpath;
78     return;
79   }
80   dirent* entry;
81   while ((entry = readdir(dir)) != nullptr) {
82     if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
83       continue;
84     }
85     if (IsDir(dirpath + std::string("/") + entry->d_name)) {
86       if (subdirs != nullptr) {
87         subdirs->push_back(entry->d_name);
88       }
89     } else {
90       if (files != nullptr) {
91         files->push_back(entry->d_name);
92       }
93     }
94   }
95   closedir(dir);
96 }
97
98 bool IsDir(const std::string& dirpath) {
99   struct stat st;
100   if (stat(dirpath.c_str(), &st) == 0) {
101     if (S_ISDIR(st.st_mode)) {
102       return true;
103     }
104   }
105   return false;
106 }
107
108 bool IsRegularFile(const std::string& filename) {
109   struct stat st;
110   if (stat(filename.c_str(), &st) == 0) {
111     if (S_ISREG(st.st_mode)) {
112       return true;
113     }
114   }
115   return false;
116 }
117
118 bool RemovePossibleFile(const std::string& filename) {
119   struct stat st;
120   if (stat(filename.c_str(), &st) == 0) {
121     if (!S_ISREG(st.st_mode)) {
122       LOG(ERROR) << filename << " is not a file.";
123       return false;
124     }
125     if (unlink(filename.c_str()) == -1) {
126       PLOG(ERROR) << "unlink(" << filename << ") failed";
127       return false;
128     }
129   }
130   return true;
131 }
132
133 bool StringToPid(const std::string& s, int* pid) {
134   char* endptr;
135   *pid = static_cast<int>(strtol(s.c_str(), &endptr, 10));
136   return *endptr == '\0';
137 }