diff options
author | Dan Albert <danalbert@google.com> | 2014-08-20 09:16:57 -0700 |
---|---|---|
committer | Dan Albert <danalbert@google.com> | 2014-08-22 10:23:12 -0700 |
commit | 4caa1f09770ea3e5ca22afbe8aa0900810a0dbfe (patch) | |
tree | 2bda183c2c930871e73486ea3e9c54e80e500f95 /libc | |
parent | d5fbc37119ef6cd757ceb449cb071ee03c66590e (diff) | |
download | android_bionic-4caa1f09770ea3e5ca22afbe8aa0900810a0dbfe.tar.gz android_bionic-4caa1f09770ea3e5ca22afbe8aa0900810a0dbfe.tar.bz2 android_bionic-4caa1f09770ea3e5ca22afbe8aa0900810a0dbfe.zip |
Implement malloc_info(3).
Expose jemalloc stats through the malloc_info(3) interface.
Bug: 16874689
Change-Id: I4358ac283002e60ff161107028d1a3fb1e9afb0a
Diffstat (limited to 'libc')
-rw-r--r-- | libc/Android.mk | 1 | ||||
-rw-r--r-- | libc/bionic/dlmalloc.c | 23 | ||||
-rw-r--r-- | libc/bionic/malloc_info.cpp | 94 | ||||
-rw-r--r-- | libc/bionic/malloc_info.h | 32 | ||||
-rw-r--r-- | libc/include/malloc.h | 22 |
5 files changed, 172 insertions, 0 deletions
diff --git a/libc/Android.mk b/libc/Android.mk index 487cbd80e..6beb7b388 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -135,6 +135,7 @@ libc_bionic_src_files := \ bionic/link.cpp \ bionic/locale.cpp \ bionic/lstat.cpp \ + bionic/malloc_info.cpp \ bionic/mbrtoc16.cpp \ bionic/mbrtoc32.cpp \ bionic/mbstate.cpp \ diff --git a/libc/bionic/dlmalloc.c b/libc/bionic/dlmalloc.c index e89c5d1ff..fdb1b2642 100644 --- a/libc/bionic/dlmalloc.c +++ b/libc/bionic/dlmalloc.c @@ -16,6 +16,7 @@ #include "dlmalloc.h" +#include "malloc.h" #include "private/bionic_prctl.h" #include "private/libc_logging.h" @@ -54,3 +55,25 @@ static void* named_anonymous_mmap(size_t length) { prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map, length, "libc_malloc"); return map; } + +// Since dlmalloc isn't the default, we'll leave this unimplemented for now. If +// we decide we need it later, we can fill it in. +size_t __mallinfo_narenas() { + return 0; +} + +size_t __mallinfo_nbins() { + return 0; +} + +struct mallinfo __mallinfo_arena_info(size_t) { + struct mallinfo mi; + memset(&mi, 0, sizeof(mi)); + return mi; +} + +struct mallinfo __mallinfo_bin_info(size_t, size_t) { + struct mallinfo mi; + memset(&mi, 0, sizeof(mi)); + return mi; +} diff --git a/libc/bionic/malloc_info.cpp b/libc/bionic/malloc_info.cpp new file mode 100644 index 000000000..99caedbad --- /dev/null +++ b/libc/bionic/malloc_info.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2014 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. + */ + +#include "malloc_info.h" + +#include <errno.h> +#include "private/bionic_macros.h" + +class __LIBC_HIDDEN__ Elem { +public: + // name must be valid throughout lifetime of the object. + explicit Elem(FILE* fp, const char* name, + const char* attr_fmt = nullptr, ...) { + this->fp = fp; + this->name = name; + + fprintf(fp, "<%s", name); + if (attr_fmt != nullptr) { + va_list args; + va_start(args, attr_fmt); + fputc(' ', fp); + vfprintf(fp, attr_fmt, args); + va_end(args); + } + fputc('>', fp); + } + + ~Elem() noexcept { + fprintf(fp, "</%s>", name); + } + + void contents(const char* fmt, ...) { + va_list args; + va_start(args, fmt); + vfprintf(fp, fmt, args); + va_end(args); + } + +private: + FILE* fp; + const char* name; + + DISALLOW_COPY_AND_ASSIGN(Elem); +}; + +int malloc_info(int options, FILE* fp) { + if (options != 0) { + errno = EINVAL; + return -1; + } + + Elem root(fp, "malloc", "version=\"jemalloc-1\""); + + // Dump all of the large allocations in the arenas. + for (size_t i = 0; i < __mallinfo_narenas(); i++) { + struct mallinfo mi = __mallinfo_arena_info(i); + if (mi.hblkhd != 0) { + Elem arena_elem(fp, "heap", "nr=\"%d\"", i); + { + Elem(fp, "allocated-large").contents("%zu", mi.ordblks); + Elem(fp, "allocated-huge").contents("%zu", mi.uordblks); + Elem(fp, "allocated-bins").contents("%zu", mi.fsmblks); + + size_t total = 0; + for (size_t j = 0; j < __mallinfo_nbins(); j++) { + struct mallinfo mi = __mallinfo_bin_info(i, j); + if (mi.ordblks != 0) { + Elem bin_elem(fp, "bin", "nr=\"%d\"", j); + Elem(fp, "allocated").contents("%zu", mi.ordblks); + Elem(fp, "nmalloc").contents("%zu", mi.uordblks); + Elem(fp, "ndalloc").contents("%zu", mi.fordblks); + total += mi.ordblks; + } + } + Elem(fp, "bins-total").contents("%zu", total); + } + } + } + + return 0; +} diff --git a/libc/bionic/malloc_info.h b/libc/bionic/malloc_info.h new file mode 100644 index 000000000..5fffae980 --- /dev/null +++ b/libc/bionic/malloc_info.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2014 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. + */ + +#ifndef LIBC_BIONIC_MALLOC_INFO_H_ +#define LIBC_BIONIC_MALLOC_INFO_H_ + +#include <malloc.h> +#include <sys/cdefs.h> + +__BEGIN_DECLS + +__LIBC_HIDDEN__ size_t __mallinfo_narenas(); +__LIBC_HIDDEN__ size_t __mallinfo_nbins(); +__LIBC_HIDDEN__ struct mallinfo __mallinfo_arena_info(size_t); +__LIBC_HIDDEN__ struct mallinfo __mallinfo_bin_info(size_t, size_t); + +__END_DECLS + +#endif // LIBC_BIONIC_MALLOC_INFO_H_ diff --git a/libc/include/malloc.h b/libc/include/malloc.h index e6ea27606..cb1dd3bcf 100644 --- a/libc/include/malloc.h +++ b/libc/include/malloc.h @@ -24,6 +24,7 @@ */ #include <sys/cdefs.h> #include <stddef.h> +#include <stdio.h> __BEGIN_DECLS @@ -53,6 +54,27 @@ struct mallinfo { extern struct mallinfo mallinfo(void); +/* + * XML structure for malloc_info(3) is in the following format: + * + * <malloc version="jemalloc-1"> + * <heap nr="INT"> + * <allocated-large>INT</allocated-large> + * <allocated-huge>INT</allocated-huge> + * <allocated-bins>INT</allocated-bins> + * <bins-total>INT</bins-total> + * <bin nr="INT"> + * <allocated>INT</allocated> + * <nmalloc>INT</nmalloc> + * <ndalloc>INT</ndalloc> + * </bin> + * <!-- more bins --> + * </heap> + * <!-- more heaps --> + * </malloc> + */ +extern int malloc_info(int, FILE *); + __END_DECLS #endif /* LIBC_INCLUDE_MALLOC_H_ */ |