consolidate do_mallinfo{,2}

We had 2 nearly identical implementations. Thankfully C++ templates
facility lets us produce 2 different runtime functions (for different
type widths) without duplicating source.

Amend github issue #1414
This commit is contained in:
Aliaksey Kandratsenka 2023-12-07 15:01:27 -05:00
parent b8e75ae6fe
commit 85048430ac
2 changed files with 26 additions and 48 deletions

View File

@ -1573,13 +1573,13 @@ extern "C" PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) PERFTOOLS_NOTHR
#ifdef HAVE_STRUCT_MALLINFO
extern "C" PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) PERFTOOLS_NOTHROW {
return do_mallinfo();
return do_mallinfo<struct mallinfo>();
}
#endif
#ifdef HAVE_STRUCT_MALLINFO2
extern "C" PERFTOOLS_DLL_DECL struct mallinfo2 tc_mallinfo2(void) PERFTOOLS_NOTHROW {
return do_mallinfo2();
return do_mallinfo<struct mallinfo2>();
}
#endif

View File

@ -1673,59 +1673,37 @@ inline int do_mallopt(int cmd, int value) {
return 1; // Indicates error
}
#ifdef HAVE_STRUCT_MALLINFO
inline struct mallinfo do_mallinfo() {
#if defined(HAVE_STRUCT_MALLINFO) || defined(HAVE_STRUCT_MALLINFO2)
template <typename Mallinfo>
inline Mallinfo do_mallinfo() {
TCMallocStats stats;
ExtractStats(&stats, NULL, NULL, NULL);
// Just some of the fields are filled in.
struct mallinfo info;
Mallinfo info;
memset(&info, 0, sizeof(info));
// Unfortunately, the struct contains "int" field, so some of the
// size values will be truncated.
info.arena = static_cast<int>(stats.pageheap.system_bytes);
info.fsmblks = static_cast<int>(stats.thread_bytes
+ stats.central_bytes
+ stats.transfer_bytes);
info.fordblks = static_cast<int>(stats.pageheap.free_bytes +
stats.pageheap.unmapped_bytes);
info.uordblks = static_cast<int>(stats.pageheap.system_bytes
- stats.thread_bytes
- stats.central_bytes
- stats.transfer_bytes
- stats.pageheap.free_bytes
- stats.pageheap.unmapped_bytes);
// Note, struct mallinfo contains "int" fields, so some of the size
// values will be truncated. But thankfully we also have
// mallinfo2. We're able to produce code for both of those variants.
using inttp = decltype(info.arena); // int or size_t in practice
info.arena = static_cast<inttp>(stats.pageheap.system_bytes);
info.fsmblks = static_cast<inttp>(stats.thread_bytes
+ stats.central_bytes
+ stats.transfer_bytes);
info.fordblks = static_cast<inttp>(stats.pageheap.free_bytes +
stats.pageheap.unmapped_bytes);
info.uordblks = static_cast<inttp>(stats.pageheap.system_bytes
- stats.thread_bytes
- stats.central_bytes
- stats.transfer_bytes
- stats.pageheap.free_bytes
- stats.pageheap.unmapped_bytes);
return info;
}
#endif // HAVE_STRUCT_MALLINFO
#ifdef HAVE_STRUCT_MALLINFO2
inline struct mallinfo2 do_mallinfo2() {
TCMallocStats stats;
ExtractStats(&stats, NULL, NULL, NULL);
// Just some of the fields are filled in.
struct mallinfo2 info;
memset(&info, 0, sizeof(info));
info.arena = static_cast<size_t>(stats.pageheap.system_bytes);
info.fsmblks = static_cast<size_t>(stats.thread_bytes
+ stats.central_bytes
+ stats.transfer_bytes);
info.fordblks = static_cast<size_t>(stats.pageheap.free_bytes +
stats.pageheap.unmapped_bytes);
info.uordblks = static_cast<size_t>(stats.pageheap.system_bytes
- stats.thread_bytes
- stats.central_bytes
- stats.transfer_bytes
- stats.pageheap.free_bytes
- stats.pageheap.unmapped_bytes);
return info;
}
#endif // HAVE_STRUCT_MALLINFO2
#endif // HAVE_STRUCT_MALLINFO || HAVE_STRUCT_MALLINFO2
} // end unnamed namespace
@ -2241,13 +2219,13 @@ extern "C" PERFTOOLS_DLL_DECL int tc_mallopt(int cmd, int value) PERFTOOLS_NOTHR
#ifdef HAVE_STRUCT_MALLINFO
extern "C" PERFTOOLS_DLL_DECL struct mallinfo tc_mallinfo(void) PERFTOOLS_NOTHROW {
return do_mallinfo();
return do_mallinfo<struct mallinfo>();
}
#endif
#ifdef HAVE_STRUCT_MALLINFO2
extern "C" PERFTOOLS_DLL_DECL struct mallinfo2 tc_mallinfo2(void) PERFTOOLS_NOTHROW {
return do_mallinfo2();
return do_mallinfo<struct mallinfo2>();
}
#endif