Add mallinfo2 call.
Bug: 208293616 Test: New unit tests pass. Change-Id: I619219b7322e2dd1c82b9c8a171dfbfe7eac6706
This commit is contained in:
parent
6769ccbe88
commit
8248e62fa9
|
@ -97,30 +97,31 @@ void* memalign(size_t __alignment, size_t __byte_count) __mallocfunc __BIONIC_AL
|
|||
*/
|
||||
size_t malloc_usable_size(const void* __ptr) __INTRODUCED_IN(17);
|
||||
|
||||
#define __MALLINFO_BODY \
|
||||
/** Total number of non-mmapped bytes currently allocated from OS. */ \
|
||||
size_t arena; \
|
||||
/** Number of free chunks. */ \
|
||||
size_t ordblks; \
|
||||
/** (Unused.) */ \
|
||||
size_t smblks; \
|
||||
/** (Unused.) */ \
|
||||
size_t hblks; \
|
||||
/** Total number of bytes in mmapped regions. */ \
|
||||
size_t hblkhd; \
|
||||
/** Maximum total allocated space; greater than total if trimming has occurred. */ \
|
||||
size_t usmblks; \
|
||||
/** (Unused.) */ \
|
||||
size_t fsmblks; \
|
||||
/** Total allocated space (normal or mmapped.) */ \
|
||||
size_t uordblks; \
|
||||
/** Total free space. */ \
|
||||
size_t fordblks; \
|
||||
/** Upper bound on number of bytes releasable by a trim operation. */ \
|
||||
size_t keepcost;
|
||||
|
||||
#ifndef STRUCT_MALLINFO_DECLARED
|
||||
#define STRUCT_MALLINFO_DECLARED 1
|
||||
struct mallinfo {
|
||||
/** Total number of non-mmapped bytes currently allocated from OS. */
|
||||
size_t arena;
|
||||
/** Number of free chunks. */
|
||||
size_t ordblks;
|
||||
/** (Unused.) */
|
||||
size_t smblks;
|
||||
/** (Unused.) */
|
||||
size_t hblks;
|
||||
/** Total number of bytes in mmapped regions. */
|
||||
size_t hblkhd;
|
||||
/** Maximum total allocated space; greater than total if trimming has occurred. */
|
||||
size_t usmblks;
|
||||
/** (Unused.) */
|
||||
size_t fsmblks;
|
||||
/** Total allocated space (normal or mmapped.) */
|
||||
size_t uordblks;
|
||||
/** Total free space. */
|
||||
size_t fordblks;
|
||||
/** Upper bound on number of bytes releasable by a trim operation. */
|
||||
size_t keepcost;
|
||||
};
|
||||
struct mallinfo { __MALLINFO_BODY };
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -130,6 +131,18 @@ struct mallinfo {
|
|||
*/
|
||||
struct mallinfo mallinfo(void);
|
||||
|
||||
/**
|
||||
* On Android the struct mallinfo and struct mallinfo2 are the same.
|
||||
*/
|
||||
struct mallinfo2 { __MALLINFO_BODY };
|
||||
|
||||
/**
|
||||
* [mallinfo2(3)](http://man7.org/linux/man-pages/man3/mallinfo2.3.html) returns
|
||||
* information about the current state of the heap. Note that mallinfo2() is
|
||||
* inherently unreliable and consider using malloc_info() instead.
|
||||
*/
|
||||
struct mallinfo2 mallinfo2(void) __RENAME(mallinfo);
|
||||
|
||||
/**
|
||||
* [malloc_info(3)](http://man7.org/linux/man-pages/man3/malloc_info.3.html)
|
||||
* writes information about the current state of the heap to the given stream.
|
||||
|
|
|
@ -809,6 +809,77 @@ TEST(malloc, mallinfo) {
|
|||
#endif
|
||||
}
|
||||
|
||||
TEST(malloc, mallinfo2) {
|
||||
#if defined(__BIONIC__)
|
||||
SKIP_WITH_HWASAN << "hwasan does not implement mallinfo2";
|
||||
static size_t sizes[] = {8, 32, 128, 4096, 32768, 131072, 1024000, 10240000, 20480000, 300000000};
|
||||
|
||||
constexpr static size_t kMaxAllocs = 50;
|
||||
|
||||
for (size_t size : sizes) {
|
||||
// If some of these allocations are stuck in a thread cache, then keep
|
||||
// looping until we make an allocation that changes the total size of the
|
||||
// memory allocated.
|
||||
// jemalloc implementations counts the thread cache allocations against
|
||||
// total memory allocated.
|
||||
void* ptrs[kMaxAllocs] = {};
|
||||
bool pass = false;
|
||||
for (size_t i = 0; i < kMaxAllocs; i++) {
|
||||
struct mallinfo info = mallinfo();
|
||||
struct mallinfo2 info2 = mallinfo2();
|
||||
// Verify that mallinfo and mallinfo2 are exactly the same.
|
||||
ASSERT_EQ(info.arena, info2.arena);
|
||||
ASSERT_EQ(info.ordblks, info2.ordblks);
|
||||
ASSERT_EQ(info.smblks, info2.smblks);
|
||||
ASSERT_EQ(info.hblks, info2.hblks);
|
||||
ASSERT_EQ(info.hblkhd, info2.hblkhd);
|
||||
ASSERT_EQ(info.usmblks, info2.usmblks);
|
||||
ASSERT_EQ(info.fsmblks, info2.fsmblks);
|
||||
ASSERT_EQ(info.uordblks, info2.uordblks);
|
||||
ASSERT_EQ(info.fordblks, info2.fordblks);
|
||||
ASSERT_EQ(info.keepcost, info2.keepcost);
|
||||
|
||||
size_t allocated = info2.uordblks;
|
||||
ptrs[i] = malloc(size);
|
||||
ASSERT_TRUE(ptrs[i] != nullptr);
|
||||
|
||||
info = mallinfo();
|
||||
info2 = mallinfo2();
|
||||
// Verify that mallinfo and mallinfo2 are exactly the same.
|
||||
ASSERT_EQ(info.arena, info2.arena);
|
||||
ASSERT_EQ(info.ordblks, info2.ordblks);
|
||||
ASSERT_EQ(info.smblks, info2.smblks);
|
||||
ASSERT_EQ(info.hblks, info2.hblks);
|
||||
ASSERT_EQ(info.hblkhd, info2.hblkhd);
|
||||
ASSERT_EQ(info.usmblks, info2.usmblks);
|
||||
ASSERT_EQ(info.fsmblks, info2.fsmblks);
|
||||
ASSERT_EQ(info.uordblks, info2.uordblks);
|
||||
ASSERT_EQ(info.fordblks, info2.fordblks);
|
||||
ASSERT_EQ(info.keepcost, info2.keepcost);
|
||||
|
||||
size_t new_allocated = info2.uordblks;
|
||||
if (allocated != new_allocated) {
|
||||
size_t usable_size = malloc_usable_size(ptrs[i]);
|
||||
// Only check if the total got bigger by at least allocation size.
|
||||
// Sometimes the mallinfo2 numbers can go backwards due to compaction
|
||||
// and/or freeing of cached data.
|
||||
if (new_allocated >= allocated + usable_size) {
|
||||
pass = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (void* ptr : ptrs) {
|
||||
free(ptr);
|
||||
}
|
||||
ASSERT_TRUE(pass) << "For size " << size << " allocated bytes did not increase after "
|
||||
<< kMaxAllocs << " allocations.";
|
||||
}
|
||||
#else
|
||||
GTEST_SKIP() << "glibc is broken";
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void __attribute__((optnone)) VerifyAlignment(Type* floating) {
|
||||
size_t expected_alignment = alignof(Type);
|
||||
|
|
Loading…
Reference in New Issue