Clean up malloc stress test.
Use starts_with for strings instead of the android base function.
Add a method to dump the allocator stats every 100 passes.
Test: Ran memory stress test.
Change-Id: I2392facd1393ecc3371bebf9b2dea8486ba9c58c
diff --git a/tests/malloc_stress_test.cpp b/tests/malloc_stress_test.cpp
index b5b06ab..00f5919 100644
--- a/tests/malloc_stress_test.cpp
+++ b/tests/malloc_stress_test.cpp
@@ -27,10 +27,58 @@
#include <thread>
#include <vector>
-#include <android-base/strings.h>
#if defined(__BIONIC__)
#include <meminfo/procmeminfo.h>
#include <procinfo/process_map.h>
+
+#include <log/log.h>
+#include <log/log_read.h>
+#endif
+
+#if defined(__BIONIC__)
+static void PrintLogStats(uint64_t& last_time) {
+ logger_list* logger =
+ android_logger_list_open(android_name_to_log_id("main"), ANDROID_LOG_NONBLOCK, 0, getpid());
+ if (logger == nullptr) {
+ printf("Failed to open log for main\n");
+ return;
+ }
+
+ uint64_t last_message_time = last_time;
+ while (true) {
+ log_msg entry;
+ ssize_t retval = android_logger_list_read(logger, &entry);
+ if (retval == 0) {
+ break;
+ }
+ if (retval < 0) {
+ if (retval == -EINTR) {
+ continue;
+ }
+ // EAGAIN means there is nothing left to read when ANDROID_LOG_NONBLOCK is set.
+ if (retval != -EAGAIN) {
+ printf("Failed to read log entry: %s\n", strerrordesc_np(retval));
+ }
+ break;
+ }
+ if (entry.msg() == nullptr) {
+ continue;
+ }
+ // Only print allocator tagged log entries.
+ std::string_view tag(entry.msg() + 1);
+ if (tag != "scudo" && tag != "jemalloc") {
+ continue;
+ }
+ if (entry.nsec() > last_time) {
+ printf(" %s\n", &tag.back() + 2);
+ // Only update the last time outside this loop just in case two or more
+ // messages have the same timestamp.
+ last_message_time = entry.nsec();
+ }
+ }
+ android_logger_list_close(logger);
+ last_time = last_message_time;
+}
#endif
TEST(malloc_stress, multiple_threads_forever) {
@@ -45,6 +93,8 @@
#endif
uint64_t mallinfo_min = UINT64_MAX;
uint64_t mallinfo_max = 0;
+
+ uint64_t last_message_time = 0;
for (size_t i = 0; ; i++) {
printf("Pass %zu\n", i);
@@ -74,8 +124,8 @@
uint64_t rss_bytes = 0;
uint64_t vss_bytes = 0;
for (auto& vma : maps) {
- if (vma.name == "[anon:libc_malloc]" || android::base::StartsWith(vma.name, "[anon:scudo:") ||
- android::base::StartsWith(vma.name, "[anon:GWP-ASan")) {
+ if (vma.name == "[anon:libc_malloc]" || vma.name.starts_with("[anon:scudo:") ||
+ vma.name.starts_with("[anon:GWP-ASan")) {
android::meminfo::Vma update_vma(vma);
ASSERT_TRUE(proc_mem.FillInVmaStats(update_vma));
rss_bytes += update_vma.usage.rss;
@@ -112,5 +162,15 @@
printf("Allocated memory %zu %0.2fMB\n", mallinfo_bytes, mallinfo_bytes / (1024.0 * 1024.0));
printf(" Min %" PRIu64 " %0.2fMB\n", mallinfo_min, mallinfo_min / (1024.0 * 1024.0));
printf(" Max %" PRIu64 " %0.2fMB\n", mallinfo_max, mallinfo_max / (1024.0 * 1024.0));
+
+#if defined(__BIONIC__)
+ if (((i + 1) % 100) == 0) {
+ // Send native allocator stats to the log
+ mallopt(M_LOG_STATS, 0);
+
+ printf("Log stats:\n");
+ PrintLogStats(last_message_time);
+ }
+#endif
}
}