aboutsummaryrefslogtreecommitdiff
path: root/benchmarks/get_heap_size_benchmark.cpp
diff options
context:
space:
mode:
authorHans Boehm <hboehm@google.com>2018-10-18 10:37:34 -0700
committerHans Boehm <hboehm@google.com>2018-10-18 17:56:58 -0700
commit3e5754c6ad6baf9f80885dc41c39854eb0bfb067 (patch)
tree4190f76386f30e73939c5caebe596da6e9aec01e /benchmarks/get_heap_size_benchmark.cpp
parenta2af8bea8c6c4b6ce6883bf92cbce922e0d9f458 (diff)
downloadbionic-3e5754c6ad6baf9f80885dc41c39854eb0bfb067.tar.gz
Add benchmarks for heap size retrieval
Add benchmarks for mallinfo, and for retrieving RSS from /proc/self/statm, since we're considering using these for GC triggering. Add some static linkage specifiers, after running into a build problem due to a spurious conflict. Bug: 111447610 Test: Ran benchmarks Change-Id: Ie50d512294993882728c63ce51ec507590257d80
Diffstat (limited to 'benchmarks/get_heap_size_benchmark.cpp')
-rw-r--r--benchmarks/get_heap_size_benchmark.cpp98
1 files changed, 98 insertions, 0 deletions
diff --git a/benchmarks/get_heap_size_benchmark.cpp b/benchmarks/get_heap_size_benchmark.cpp
new file mode 100644
index 000000000..c3680dc44
--- /dev/null
+++ b/benchmarks/get_heap_size_benchmark.cpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// This measures the time required to compute two different native heap size metrics that
+// we might use to guide GC triggering.
+
+#include <atomic>
+#include <err.h>
+#include <fcntl.h>
+#include <malloc.h>
+#include <pthread.h>
+#include <sched.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <benchmark/benchmark.h>
+#include "util.h"
+
+static volatile size_t sink;
+
+static constexpr int NTHREADS = 5;
+
+static std::atomic<int> thread_count;
+
+static void* thread_func(void* arg) {
+ *reinterpret_cast<void**>(arg) = malloc(17);
+ thread_count++;
+ return nullptr;
+}
+
+static void BM_mallinfo(benchmark::State& state) {
+ pthread_t t[NTHREADS];
+ void* object[NTHREADS];
+ // Create threads to populate thread-local arenas, if any.
+ thread_count = 0;
+ for (int i = 0; i < 5; i++) {
+ int res = pthread_create(t + i, NULL, thread_func, object + i);
+ if (res != 0) {
+ errx(1, "ERROR: pthread_create failed");
+ }
+ }
+ while (thread_count != NTHREADS) {
+ sched_yield();
+ }
+ for (auto _ : state) {
+ sink = mallinfo().uordblks;
+ }
+ for (int i = 0; i < 5; i++) {
+ int res = pthread_join(t[i], NULL);
+ if (res != 0) {
+ errx(1, "ERROR: pthread_join failed");
+ }
+ free(object[i]);
+ }
+}
+
+BIONIC_BENCHMARK(BM_mallinfo);
+
+static constexpr int BUF_SIZE = 100;
+
+static void BM_read_statm(benchmark::State& state) {
+ char buf[BUF_SIZE];
+ int statm_fd = open("/proc/self/statm", O_RDONLY);
+ if (statm_fd == -1) {
+ errx(1, "ERROR: Open failed");
+ }
+ for (auto _ : state) {
+ off_t result = lseek(statm_fd, 0 /* offset */, SEEK_SET);
+ if (result == (off_t) -1) {
+ errx(1, "ERROR: lseek to beginning failed");
+ }
+ ssize_t nread = read(statm_fd, buf, BUF_SIZE);
+ if (nread < 13 || nread > 50) {
+ errx(1, "ERROR: Implausible read result; result = %zd", nread);
+ }
+ // We should really add the parsing overhead for the result; but that should be < 100 nsecs
+ // if we tweak it enough.
+ }
+ if (close(statm_fd) == -1) {
+ errx(1, "ERROR: Close failed");
+ }
+}
+
+BIONIC_BENCHMARK(BM_read_statm);