File indexing completed on 2024-10-23 22:48:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <dlfcn.h> // dlsym
0015
0016
0017 #include "PerfTools/AllocMonitor/interface/AllocMonitorRegistry.h"
0018 #include "FWCore/Utilities/interface/Exception.h"
0019 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0020
0021
0022
0023
0024 extern "C" {
0025 void alloc_monitor_start();
0026 void alloc_monitor_stop();
0027 bool alloc_monitor_stop_thread_reporting();
0028 void alloc_monitor_start_thread_reporting();
0029 }
0030
0031 namespace {
0032 bool& dummyThreadReportingFcn() {
0033 static thread_local bool s_running = true;
0034 return s_running;
0035 }
0036
0037 bool dummyStopThreadReportingFcn() {
0038 auto& t = dummyThreadReportingFcn();
0039 auto last = t;
0040 t = false;
0041 return last;
0042 }
0043
0044 void dummyStartThreadReportingFcn() { dummyThreadReportingFcn() = true; }
0045
0046 bool stopThreadReporting() {
0047 static decltype(&::alloc_monitor_stop_thread_reporting) s_fcn = []() {
0048 void* fcn = dlsym(RTLD_DEFAULT, "alloc_monitor_stop_thread_reporting");
0049 if (fcn != nullptr) {
0050 return reinterpret_cast<decltype(&::alloc_monitor_stop_thread_reporting)>(fcn);
0051 }
0052
0053 return &::dummyStopThreadReportingFcn;
0054 }();
0055 return s_fcn();
0056 }
0057
0058 void startThreadReporting() {
0059 static decltype(&::alloc_monitor_start_thread_reporting) s_fcn = []() {
0060 void* fcn = dlsym(RTLD_DEFAULT, "alloc_monitor_start_thread_reporting");
0061 if (fcn != nullptr) {
0062 return reinterpret_cast<decltype(&::alloc_monitor_start_thread_reporting)>(fcn);
0063 }
0064
0065 return &::dummyStartThreadReportingFcn;
0066 }();
0067 s_fcn();
0068 }
0069 }
0070
0071 using namespace cms::perftools;
0072
0073
0074
0075
0076
0077
0078
0079
0080 AllocMonitorRegistry::AllocMonitorRegistry() {
0081
0082
0083
0084 startReporting();
0085 }
0086
0087 AllocMonitorRegistry::~AllocMonitorRegistry() {
0088 void* stop = dlsym(RTLD_DEFAULT, "alloc_monitor_stop");
0089 if (stop != nullptr) {
0090 auto s = reinterpret_cast<decltype(&::alloc_monitor_stop)>(stop);
0091 s();
0092 }
0093 stopReporting();
0094 monitors_.clear();
0095 }
0096
0097
0098
0099
0100 bool AllocMonitorRegistry::necessaryLibraryWasPreloaded() {
0101 return dlsym(RTLD_DEFAULT, "alloc_monitor_start") != nullptr;
0102 }
0103
0104 void AllocMonitorRegistry::start() {
0105 if (monitors_.empty()) {
0106 void* start = dlsym(RTLD_DEFAULT, "alloc_monitor_start");
0107 if (start == nullptr) {
0108 throw cms::Exception("NoAllocMonitorPreload")
0109 << "The libPerfToolsAllocMonitorPreload.so was not LD_PRELOADed into the job";
0110 }
0111 auto s = reinterpret_cast<decltype(&::alloc_monitor_start)>(start);
0112 s();
0113 }
0114 }
0115
0116 bool AllocMonitorRegistry::stopReporting() { return stopThreadReporting(); }
0117 void AllocMonitorRegistry::startReporting() { startThreadReporting(); }
0118
0119 void AllocMonitorRegistry::deregisterMonitor(AllocMonitorBase* iMonitor) {
0120 for (auto it = monitors_.begin(); monitors_.end() != it; ++it) {
0121 if (it->get() == iMonitor) {
0122 [[maybe_unused]] Guard g = makeGuard();
0123 monitors_.erase(it);
0124 break;
0125 }
0126 }
0127 }
0128
0129
0130
0131
0132 void AllocMonitorRegistry::allocCalled_(size_t iRequested, size_t iActual, void const* iPtr) {
0133 for (auto& m : monitors_) {
0134 m->allocCalled(iRequested, iActual, iPtr);
0135 }
0136 }
0137 void AllocMonitorRegistry::deallocCalled_(size_t iActual, void const* iPtr) {
0138 for (auto& m : monitors_) {
0139 m->deallocCalled(iActual, iPtr);
0140 }
0141 }
0142
0143
0144
0145
0146 AllocMonitorRegistry& AllocMonitorRegistry::instance() {
0147
0148 CMS_SA_ALLOW static AllocMonitorRegistry s_registry;
0149 return s_registry;
0150 }