blob: 1db08242a93e1d352412b539571e6bf9dbbf4580 [file] [log] [blame]
Sandeep Patil54d87212018-08-29 17:10:47 -07001/*
2 * Copyright (C) 2018 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 <meminfo/sysmeminfo.h>
18
19#include <fcntl.h>
Sandeep Patil70fa72d2018-11-09 19:18:29 -080020#include <inttypes.h>
21#include <stdio.h>
Sandeep Patil54d87212018-08-29 17:10:47 -070022#include <sys/stat.h>
23#include <sys/types.h>
24
25#include <string>
26
27#include <android-base/file.h>
28#include <android-base/logging.h>
Sandeep Patil54d87212018-08-29 17:10:47 -070029
30#include <benchmark/benchmark.h>
31
32enum {
33 MEMINFO_TOTAL,
34 MEMINFO_FREE,
35 MEMINFO_BUFFERS,
36 MEMINFO_CACHED,
37 MEMINFO_SHMEM,
38 MEMINFO_SLAB,
39 MEMINFO_SLAB_RECLAIMABLE,
40 MEMINFO_SLAB_UNRECLAIMABLE,
41 MEMINFO_SWAP_TOTAL,
42 MEMINFO_SWAP_FREE,
43 MEMINFO_ZRAM_TOTAL,
44 MEMINFO_MAPPED,
45 MEMINFO_VMALLOC_USED,
46 MEMINFO_PAGE_TABLES,
47 MEMINFO_KERNEL_STACK,
48 MEMINFO_COUNT
49};
50
Sandeep Patil70fa72d2018-11-09 19:18:29 -080051static void get_mem_info(uint64_t mem[], const char* file) {
Sandeep Patil54d87212018-08-29 17:10:47 -070052 char buffer[4096];
53 unsigned int numFound = 0;
54
55 int fd = open(file, O_RDONLY);
56
57 if (fd < 0) {
58 printf("Unable to open %s: %s\n", file, strerror(errno));
59 return;
60 }
61
62 const int len = read(fd, buffer, sizeof(buffer) - 1);
63 close(fd);
64
65 if (len < 0) {
66 printf("Empty %s\n", file);
67 return;
68 }
69 buffer[len] = 0;
70
71 static const char* const tags[] = {
Sandeep Patil70fa72d2018-11-09 19:18:29 -080072 "MemTotal:", "MemFree:", "Buffers:", "Cached:", "Shmem:", "Slab:",
73 "SReclaimable:", "SUnreclaim:", "SwapTotal:", "SwapFree:", "ZRam:", "Mapped:",
74 "VmallocUsed:", "PageTables:", "KernelStack:", NULL
75 };
Sandeep Patil54d87212018-08-29 17:10:47 -070076
77 static const int tagsLen[] = {9, 8, 8, 7, 6, 5, 13, 11, 10, 9, 5, 7, 12, 11, 12, 0};
78
79 memset(mem, 0, sizeof(uint64_t) * 15);
80 char* p = buffer;
81 while (*p && (numFound < (sizeof(tagsLen) / sizeof(tagsLen[0])))) {
82 int i = 0;
83 while (tags[i]) {
Sandeep Patil70fa72d2018-11-09 19:18:29 -080084 // std::cout << "tag =" << tags[i] << " p = " << std::string(p, tagsLen[i]) <<
85 // std::endl;
Sandeep Patil54d87212018-08-29 17:10:47 -070086 if (strncmp(p, tags[i], tagsLen[i]) == 0) {
87 p += tagsLen[i];
88 while (*p == ' ') p++;
89 char* num = p;
90 while (*p >= '0' && *p <= '9') p++;
91 if (*p != 0) {
92 *p = 0;
93 p++;
94 }
95 mem[i] = atoll(num);
96 numFound++;
97 break;
98 }
99 i++;
100 }
101 while (*p && *p != '\n') {
102 p++;
103 }
104 if (*p) p++;
105 }
106}
107
108static void BM_ParseSysMemInfo(benchmark::State& state) {
109 std::string meminfo = R"meminfo(MemTotal: 3019740 kB
110MemFree: 1809728 kB
111MemAvailable: 2546560 kB
112Buffers: 54736 kB
113Cached: 776052 kB
114SwapCached: 0 kB
115Active: 445856 kB
116Inactive: 459092 kB
117Active(anon): 78492 kB
118Inactive(anon): 2240 kB
119Active(file): 367364 kB
120Inactive(file): 456852 kB
121Unevictable: 3096 kB
122Mlocked: 3096 kB
123SwapTotal: 0 kB
124SwapFree: 0 kB
125Dirty: 32 kB
126Writeback: 0 kB
127AnonPages: 74988 kB
128Mapped: 62624 kB
129Shmem: 4020 kB
130Slab: 86464 kB
131SReclaimable: 44432 kB
132SUnreclaim: 42032 kB
133KernelStack: 4880 kB
134PageTables: 2900 kB
135NFS_Unstable: 0 kB
136Bounce: 0 kB
137WritebackTmp: 0 kB
138CommitLimit: 1509868 kB
139Committed_AS: 80296 kB
140VmallocTotal: 263061440 kB
141VmallocUsed: 0 kB
142VmallocChunk: 0 kB
143AnonHugePages: 6144 kB
144ShmemHugePages: 0 kB
145ShmemPmdMapped: 0 kB
146CmaTotal: 131072 kB
147CmaFree: 130380 kB
148HugePages_Total: 0
149HugePages_Free: 0
150HugePages_Rsvd: 0
151HugePages_Surp: 0
152Hugepagesize: 2048 kB)meminfo";
153
154 TemporaryFile tf;
155 ::android::base::WriteStringToFd(meminfo, tf.fd);
156
157 uint64_t mem[MEMINFO_COUNT];
158 for (auto _ : state) {
159 get_mem_info(mem, tf.path);
160 }
161}
162BENCHMARK(BM_ParseSysMemInfo);
163
164static void BM_ReadMemInfo(benchmark::State& state) {
165 std::string meminfo = R"meminfo(MemTotal: 3019740 kB
166MemFree: 1809728 kB
167MemAvailable: 2546560 kB
168Buffers: 54736 kB
169Cached: 776052 kB
170SwapCached: 0 kB
171Active: 445856 kB
172Inactive: 459092 kB
173Active(anon): 78492 kB
174Inactive(anon): 2240 kB
175Active(file): 367364 kB
176Inactive(file): 456852 kB
177Unevictable: 3096 kB
178Mlocked: 3096 kB
179SwapTotal: 0 kB
180SwapFree: 0 kB
181Dirty: 32 kB
182Writeback: 0 kB
183AnonPages: 74988 kB
184Mapped: 62624 kB
185Shmem: 4020 kB
186Slab: 86464 kB
187SReclaimable: 44432 kB
188SUnreclaim: 42032 kB
189KernelStack: 4880 kB
190PageTables: 2900 kB
191NFS_Unstable: 0 kB
192Bounce: 0 kB
193WritebackTmp: 0 kB
194CommitLimit: 1509868 kB
195Committed_AS: 80296 kB
196VmallocTotal: 263061440 kB
197VmallocUsed: 0 kB
198VmallocChunk: 0 kB
199AnonHugePages: 6144 kB
200ShmemHugePages: 0 kB
201ShmemPmdMapped: 0 kB
202CmaTotal: 131072 kB
203CmaFree: 130380 kB
204HugePages_Total: 0
205HugePages_Free: 0
206HugePages_Rsvd: 0
207HugePages_Surp: 0
208Hugepagesize: 2048 kB)meminfo";
209
210 TemporaryFile tf;
211 android::base::WriteStringToFd(meminfo, tf.fd);
212
213 std::string file = std::string(tf.path);
214 ::android::meminfo::SysMemInfo mi;
215 for (auto _ : state) {
216 mi.ReadMemInfo(file);
217 }
218}
219BENCHMARK(BM_ReadMemInfo);
220
Sandeep Patil70fa72d2018-11-09 19:18:29 -0800221static uint64_t get_zram_mem_used(const std::string& zram_dir) {
222 FILE* f = fopen((zram_dir + "mm_stat").c_str(), "r");
223 if (f) {
224 uint64_t mem_used_total = 0;
225
226 int matched = fscanf(f, "%*d %*d %" SCNu64 " %*d %*d %*d %*d", &mem_used_total);
227 if (matched != 1)
228 fprintf(stderr, "warning: failed to parse %s\n", (zram_dir + "mm_stat").c_str());
229
230 fclose(f);
231 return mem_used_total;
232 }
233
234 f = fopen((zram_dir + "mem_used_total").c_str(), "r");
235 if (f) {
236 uint64_t mem_used_total = 0;
237
238 int matched = fscanf(f, "%" SCNu64, &mem_used_total);
239 if (matched != 1)
240 fprintf(stderr, "warning: failed to parse %s\n", (zram_dir + "mem_used_total").c_str());
241
242 fclose(f);
243 return mem_used_total;
244 }
245
246 return 0;
247}
248
249static void BM_OldReadZramTotal(benchmark::State& state) {
250 std::string exec_dir = ::android::base::GetExecutableDirectory();
251 std::string zram_mmstat_dir = exec_dir + "/testdata1/";
252 for (auto _ : state) {
253 uint64_t zram_total __attribute__((unused)) = get_zram_mem_used(zram_mmstat_dir) / 1024;
254 }
255}
256BENCHMARK(BM_OldReadZramTotal);
257
258static void BM_NewReadZramTotal(benchmark::State& state) {
259 std::string exec_dir = ::android::base::GetExecutableDirectory();
260 std::string zram_mmstat_dir = exec_dir + "/testdata1/";
261 ::android::meminfo::SysMemInfo mi;
262 for (auto _ : state) {
263 uint64_t zram_total __attribute__((unused)) = mi.mem_zram_kb(zram_mmstat_dir);
264 }
265}
266BENCHMARK(BM_NewReadZramTotal);
267
Sandeep Patil54d87212018-08-29 17:10:47 -0700268BENCHMARK_MAIN();