Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-06-13 03:23:56

0001 #ifndef PerfTools_AllocMonitor_AllocMonitorRegistry_h
0002 #define PerfTools_AllocMonitor_AllocMonitorRegistry_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     PerfTools/AllocMonitor
0006 // Class  :     AllocMonitorRegistry
0007 //
0008 /**\class AllocMonitorRegistry AllocMonitorRegistry.h "AllocMonitorRegistry.h"
0009 
0010  Description: [one line class summary]
0011 
0012  Usage:
0013     <usage>
0014 
0015 */
0016 //
0017 // Original Author:  Christopher Jones
0018 //         Created:  Mon, 21 Aug 2023 14:12:54 GMT
0019 //
0020 
0021 // system include files
0022 #include <memory>
0023 #include <vector>
0024 #include <malloc.h>
0025 #include <stdlib.h>
0026 
0027 // user include files
0028 #include "PerfTools/AllocMonitor/interface/AllocMonitorBase.h"
0029 
0030 // forward declarations
0031 
0032 namespace cms::perftools {
0033   class AllocTester;
0034 
0035   class AllocMonitorRegistry {
0036   public:
0037     ~AllocMonitorRegistry();
0038 
0039     AllocMonitorRegistry(AllocMonitorRegistry&&) = delete;                  // stop default
0040     AllocMonitorRegistry(const AllocMonitorRegistry&) = delete;             // stop default
0041     AllocMonitorRegistry& operator=(const AllocMonitorRegistry&) = delete;  // stop default
0042     AllocMonitorRegistry& operator=(AllocMonitorRegistry&&) = delete;       // stop default
0043 
0044     // ---------- static member functions --------------------
0045     static AllocMonitorRegistry& instance();
0046     static bool necessaryLibraryWasPreloaded();
0047 
0048     // ---------- member functions ---------------------------
0049 
0050     //The functions are not thread safe
0051     template <typename T, typename... ARGS>
0052     T* createAndRegisterMonitor(ARGS&&... iArgs);
0053     void deregisterMonitor(AllocMonitorBase*);
0054 
0055   private:
0056     friend void* ::malloc(size_t) noexcept;
0057     friend void* ::calloc(size_t, size_t) noexcept;
0058     friend void* ::realloc(void*, size_t) noexcept;
0059     friend void* ::aligned_alloc(size_t, size_t) noexcept;
0060     friend int ::posix_memalign(void**, size_t, size_t) noexcept;
0061     friend void* ::memalign(size_t, size_t) noexcept;
0062     friend void ::free(void*) noexcept;
0063 
0064     friend void* ::operator new(std::size_t size);
0065     friend void* ::operator new[](std::size_t size);
0066     friend void* ::operator new(std::size_t count, std::align_val_t al);
0067     friend void* ::operator new[](std::size_t count, std::align_val_t al);
0068     friend void* ::operator new(std::size_t count, const std::nothrow_t & tag) noexcept;
0069     friend void* ::operator new[](std::size_t count, const std::nothrow_t & tag) noexcept;
0070     friend void* ::operator new(std::size_t count, std::align_val_t al, const std::nothrow_t&) noexcept;
0071     friend void* ::operator new[](std::size_t count, std::align_val_t al, const std::nothrow_t&) noexcept;
0072 
0073     friend void ::operator delete(void* ptr) noexcept;
0074     friend void ::operator delete[](void* ptr) noexcept;
0075     friend void ::operator delete(void* ptr, std::align_val_t al) noexcept;
0076     friend void ::operator delete[](void* ptr, std::align_val_t al) noexcept;
0077     friend void ::operator delete(void* ptr, std::size_t sz) noexcept;
0078     friend void ::operator delete[](void* ptr, std::size_t sz) noexcept;
0079     friend void ::operator delete(void* ptr, std::size_t sz, std::align_val_t al) noexcept;
0080     friend void ::operator delete[](void* ptr, std::size_t sz, std::align_val_t al) noexcept;
0081     friend void ::operator delete(void* ptr, const std::nothrow_t & tag) noexcept;
0082     friend void ::operator delete[](void* ptr, const std::nothrow_t & tag) noexcept;
0083     friend void ::operator delete(void* ptr, std::align_val_t al, const std::nothrow_t & tag) noexcept;
0084     friend void ::operator delete[](void* ptr, std::align_val_t al, const std::nothrow_t & tag) noexcept;
0085 
0086     friend class AllocTester;
0087 
0088     // ---------- member data --------------------------------
0089     void start();
0090     bool stopReporting();
0091     void startReporting();
0092 
0093     struct Guard {
0094       explicit Guard(AllocMonitorRegistry& iReg) noexcept : reg_(iReg), original_(iReg.stopReporting()) {}
0095       ~Guard() {
0096         if (original_) {
0097           reg_.startReporting();
0098         }
0099       }
0100 
0101       bool shouldReport() const noexcept { return original_; }
0102 
0103       Guard(Guard const&) = delete;
0104       Guard(Guard&&) = delete;
0105       Guard& operator=(Guard const&) = delete;
0106       Guard& operator=(Guard&&) = delete;
0107 
0108     private:
0109       AllocMonitorRegistry& reg_;
0110       bool original_;
0111     };
0112 
0113     Guard makeGuard() { return Guard(*this); }
0114 
0115     void allocCalled_(size_t, size_t);
0116     void deallocCalled_(size_t);
0117 
0118     template <typename ALLOC, typename ACT>
0119     auto allocCalled(size_t iRequested, ALLOC iAlloc, ACT iGetActual) {
0120       [[maybe_unused]] Guard g = makeGuard();
0121       auto a = iAlloc();
0122       if (g.shouldReport()) {
0123         allocCalled_(iRequested, iGetActual(a));
0124       }
0125       return a;
0126     }
0127     template <typename DEALLOC, typename ACT>
0128     void deallocCalled(void* iPtr, DEALLOC iDealloc, ACT iGetActual) {
0129       [[maybe_unused]] Guard g = makeGuard();
0130       if (g.shouldReport() and iPtr != nullptr) {
0131         deallocCalled_(iGetActual(iPtr));
0132       }
0133       iDealloc(iPtr);
0134     }
0135 
0136     AllocMonitorRegistry();
0137     std::vector<std::unique_ptr<AllocMonitorBase>> monitors_;
0138   };
0139 
0140   template <typename T, typename... ARGS>
0141   T* AllocMonitorRegistry::createAndRegisterMonitor(ARGS&&... iArgs) {
0142     [[maybe_unused]] Guard guard = makeGuard();
0143     start();
0144 
0145     auto m = std::make_unique<T>(std::forward<ARGS>(iArgs)...);
0146     auto p = m.get();
0147     monitors_.push_back(std::move(m));
0148     return p;
0149   }
0150 }  // namespace cms::perftools
0151 #endif