CMS 3D CMS Logo

AllocMonitorRegistry.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: PerfTools/AllocMonitor
4 // Class : AllocMonitorRegistry
5 //
6 // Implementation:
7 // [Notes on implementation]
8 //
9 // Original Author: Christopher Jones
10 // Created: Mon, 21 Aug 2023 15:42:48 GMT
11 //
12 
13 // system include files
14 #include <dlfcn.h> // dlsym
15 
16 // user include files
20 
21 //
22 // constants, enums and typedefs
23 //
24 extern "C" {
25 void alloc_monitor_start();
26 void alloc_monitor_stop();
27 }
28 
29 namespace {
30  bool& threadRunning() {
31  static thread_local bool s_running = true;
32  return s_running;
33  }
34 } // namespace
35 
36 using namespace cms::perftools;
37 
38 //
39 // static data member definitions
40 //
41 
42 //
43 // constructors and destructor
44 //
46  threadRunning() = true;
47  //Cannot start here because statics can cause memory to be allocated in the atexit registration
48  // done behind the scenes. If the allocation happens, AllocMonitorRegistry::instance will be called
49  // recursively before the static has finished and we well deadlock
50 }
51 
53  void* stop = dlsym(RTLD_DEFAULT, "alloc_monitor_stop");
54  if (stop != nullptr) {
55  auto s = reinterpret_cast<decltype(&::alloc_monitor_stop)>(stop);
56  s();
57  }
58  threadRunning() = false;
59  monitors_.clear();
60 }
61 
62 //
63 // member functions
64 //
66  return dlsym(RTLD_DEFAULT, "alloc_monitor_start") != nullptr;
67 }
68 
70  if (monitors_.empty()) {
71  void* start = dlsym(RTLD_DEFAULT, "alloc_monitor_start");
72  if (start == nullptr) {
73  throw cms::Exception("NoAllocMonitorPreload")
74  << "The libPerfToolsAllocMonitorPreload.so was not LD_PRELOADed into the job";
75  }
76  auto s = reinterpret_cast<decltype(&::alloc_monitor_start)>(start);
77  s();
78  }
79 }
80 
81 bool& AllocMonitorRegistry::isRunning() { return threadRunning(); }
82 
84  for (auto it = monitors_.begin(); monitors_.end() != it; ++it) {
85  if (it->get() == iMonitor) {
86  [[maybe_unused]] Guard g = makeGuard();
87  monitors_.erase(it);
88  break;
89  }
90  }
91 }
92 
93 //
94 // const member functions
95 //
96 void AllocMonitorRegistry::allocCalled_(size_t iRequested, size_t iActual) {
97  for (auto& m : monitors_) {
98  m->allocCalled(iRequested, iActual);
99  }
100 }
102  for (auto& m : monitors_) {
103  m->deallocCalled(iActual);
104  }
105 }
106 
107 //
108 // static member functions
109 //
111  //The thread unsafe methods are marked as unsafe
112  CMS_SA_ALLOW static AllocMonitorRegistry s_registry;
113  return s_registry;
114 }
Definition: start.py:1
#define CMS_SA_ALLOW
void alloc_monitor_stop()
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
static AllocMonitorRegistry & instance()
std::vector< std::unique_ptr< AllocMonitorBase > > monitors_
void alloc_monitor_start()
void deregisterMonitor(AllocMonitorBase *)