File indexing completed on 2024-04-06 12:18:45
0001 #include <iostream>
0002 #include <dlfcn.h>
0003
0004 #include "HLTrigger/Timer/interface/memory_usage.h"
0005
0006
0007 extern "C" {
0008 typedef int (*mallctl_t)(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
0009 typedef int (*mallctlnametomib_t)(const char *name, size_t *mibp, size_t *miblenp);
0010 typedef int (*mallctlbymib_t)(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
0011 }
0012
0013 namespace {
0014 bool initialise();
0015 bool initialise_peak();
0016 const uint64_t *initialise_thread_allocated_p();
0017 const uint64_t *initialise_thread_deallocated_p();
0018
0019 const uint64_t zero = 0UL;
0020 size_t mib_peak_read[3];
0021 size_t mib_peak_reset[3];
0022 thread_local const uint64_t *thread_allocated_p = initialise_thread_allocated_p();
0023 thread_local const uint64_t *thread_deallocated_p = initialise_thread_deallocated_p();
0024
0025 mallctl_t mallctl = nullptr;
0026 mallctlnametomib_t mallctlnametomib = nullptr;
0027 mallctlbymib_t mallctlbymib = nullptr;
0028 const bool have_jemalloc_and_stats = initialise();
0029 const bool have_jemalloc_and_peak = have_jemalloc_and_stats and initialise_peak();
0030
0031 bool initialise() {
0032
0033 mallctl = (mallctl_t)::dlsym(RTLD_DEFAULT, "mallctl");
0034 if (mallctl == nullptr)
0035 return false;
0036 mallctlnametomib = (mallctlnametomib_t)::dlsym(RTLD_DEFAULT, "mallctlnametomib");
0037 if (mallctlnametomib == nullptr)
0038 return false;
0039 mallctlbymib = (mallctlbymib_t)::dlsym(RTLD_DEFAULT, "mallctlbymib");
0040 if (mallctlbymib == nullptr)
0041 return false;
0042
0043
0044 bool enable_stats = false;
0045 size_t bool_s = sizeof(bool);
0046 mallctl("config.stats", &enable_stats, &bool_s, nullptr, 0);
0047 return enable_stats;
0048 }
0049
0050 bool initialise_peak() {
0051
0052 size_t miblen = 3;
0053 if (mallctlnametomib("thread.peak.read", mib_peak_read, &miblen) != 0)
0054 return false;
0055 if (mallctlnametomib("thread.peak.reset", mib_peak_reset, &miblen) != 0)
0056 return false;
0057 return true;
0058 }
0059
0060 const uint64_t *initialise_thread_allocated_p() {
0061 const uint64_t *stats = &zero;
0062 size_t ptr_s = sizeof(uint64_t *);
0063
0064 if (have_jemalloc_and_stats)
0065
0066 mallctl("thread.allocatedp", &stats, &ptr_s, nullptr, 0);
0067
0068 return stats;
0069 }
0070
0071 const uint64_t *initialise_thread_deallocated_p() {
0072 const uint64_t *stats = &zero;
0073 size_t ptr_s = sizeof(uint64_t *);
0074
0075 if (have_jemalloc_and_stats)
0076
0077 mallctl("thread.deallocatedp", &stats, &ptr_s, nullptr, 0);
0078
0079 return stats;
0080 }
0081
0082 }
0083
0084 bool memory_usage::is_available() { return have_jemalloc_and_stats; }
0085
0086 uint64_t memory_usage::allocated() { return *thread_allocated_p; }
0087
0088 uint64_t memory_usage::deallocated() { return *thread_deallocated_p; }
0089
0090 uint64_t memory_usage::peak() {
0091 uint64_t peak = 0;
0092 size_t size = sizeof(uint64_t);
0093 if (have_jemalloc_and_peak)
0094 mallctlbymib(mib_peak_read, 3, &peak, &size, nullptr, 0);
0095 return peak;
0096 }
0097
0098 void memory_usage::reset_peak() {
0099 if (have_jemalloc_and_peak)
0100 mallctlbymib(mib_peak_reset, 3, nullptr, nullptr, nullptr, 0);
0101 }