Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-10-23 22:48:06

0001 #define CATCH_CONFIG_MAIN
0002 #include "catch.hpp"
0003 
0004 #include "PerfTools/AllocMonitor/interface/AllocMonitorRegistry.h"
0005 
0006 namespace cms::perftools {
0007   class AllocTester {
0008   public:
0009     void callAlloc(size_t iRequested, size_t iActual) {
0010       reg_.allocCalled(iRequested, []() { return nullptr; }, [iActual](auto) { return iActual; });
0011     }
0012 
0013     void callDealloc(size_t iActual) {
0014       reg_.deallocCalled(reinterpret_cast<void*>(1), [](auto) {}, [iActual](auto) { return iActual; });
0015     }
0016 
0017     template <typename A>
0018     void callAlloc(size_t iRequested, size_t iActual, A&& iAlloc) {
0019       reg_.allocCalled(iRequested, std::forward<A>(iAlloc), [iActual](auto) { return iActual; });
0020     }
0021 
0022     template <typename D>
0023     void callDealloc(size_t iActual, D&& iDealloc) {
0024       reg_.deallocCalled(reinterpret_cast<void*>(1), std::forward<D>(iDealloc), [iActual](auto) { return iActual; });
0025     }
0026 
0027     void callDeallocNull() {
0028       reg_.deallocCalled(nullptr, [](auto) {}, [](auto) { return 0; });
0029     }
0030 
0031     AllocMonitorRegistry reg_;
0032   };
0033 }  // namespace cms::perftools
0034 
0035 using namespace cms::perftools;
0036 
0037 namespace {
0038   int s_calls = 0;
0039 
0040   class TestCallMonitor : public AllocMonitorBase {
0041   public:
0042     TestCallMonitor(int) { ++s_calls; }
0043 
0044     ~TestCallMonitor() override { ++s_calls; }
0045 
0046     void allocCalled(size_t iRequestedSize, size_t iActualSize, void const*) final { ++s_calls; }
0047     void deallocCalled(size_t iActualSize, void const*) final { ++s_calls; }
0048   };
0049 
0050   bool s_started = false;
0051   bool s_stopped = false;
0052 
0053   class TestRecursionMonitor : public AllocMonitorBase {
0054   public:
0055     TestRecursionMonitor(AllocTester* iTester) : tester_(iTester) {
0056       ++s_calls;
0057       tester_->callAlloc(1, 1);
0058     }
0059 
0060     ~TestRecursionMonitor() override {
0061       ++s_calls;
0062       tester_->callDealloc(1);
0063     }
0064 
0065     void allocCalled(size_t iRequestedSize, size_t iActualSize, void const*) final {
0066       ++s_calls;
0067       tester_->callAlloc(1, 1);
0068       tester_->callDealloc(1);
0069     }
0070     void deallocCalled(size_t iActualSize, void const*) final {
0071       ++s_calls;
0072       tester_->callAlloc(1, 1);
0073       tester_->callDealloc(1);
0074     }
0075 
0076   private:
0077     AllocTester* tester_;
0078   };
0079 }  // namespace
0080 
0081 extern "C" {
0082 void alloc_monitor_start() { s_started = true; }
0083 void alloc_monitor_stop() { s_stopped = true; }
0084 }
0085 
0086 TEST_CASE("Test API for AllocMonitorRegistry", "[AllocMonitorRegistry]") {
0087   SECTION("Calls Check") {
0088     CHECK(0 == s_calls);
0089     CHECK(s_started == false);
0090     CHECK(s_stopped == false);
0091     {
0092       AllocTester t;
0093       CHECK(s_started == false);
0094       CHECK(s_stopped == false);
0095 
0096       auto tester = t.reg_.createAndRegisterMonitor<TestCallMonitor>(1);
0097       CHECK(s_started == true);
0098       CHECK(s_stopped == false);
0099       CHECK(1 == s_calls);
0100       CHECK(tester != nullptr);
0101 
0102       t.callAlloc(1, 1);
0103       CHECK(2 == s_calls);
0104 
0105       t.callDealloc(1);
0106       CHECK(3 == s_calls);
0107 
0108       t.reg_.deregisterMonitor(tester);
0109       CHECK(4 == s_calls);
0110     }
0111     CHECK(4 == s_calls);
0112     CHECK(s_stopped == true);
0113     s_started = false;
0114     s_stopped = false;
0115     s_calls = 0;
0116   }
0117   SECTION("Null delete") {
0118     {
0119       AllocTester t;
0120       CHECK(s_started == false);
0121       CHECK(s_stopped == false);
0122 
0123       auto tester = t.reg_.createAndRegisterMonitor<TestCallMonitor>(1);
0124       CHECK(s_started == true);
0125       CHECK(s_stopped == false);
0126       CHECK(1 == s_calls);
0127       CHECK(tester != nullptr);
0128 
0129       t.callDeallocNull();
0130       CHECK(1 == s_calls);
0131       t.reg_.deregisterMonitor(tester);
0132       CHECK(2 == s_calls);
0133     }
0134     s_started = false;
0135     s_stopped = false;
0136     s_calls = 0;
0137   }
0138   SECTION("Recursion in monitor") {
0139     CHECK(0 == s_calls);
0140     CHECK(s_started == false);
0141     CHECK(s_stopped == false);
0142     {
0143       AllocTester t;
0144       CHECK(s_started == false);
0145       CHECK(s_stopped == false);
0146 
0147       auto tester = t.reg_.createAndRegisterMonitor<TestRecursionMonitor>(&t);
0148       CHECK(s_started == true);
0149       CHECK(s_stopped == false);
0150       CHECK(1 == s_calls);
0151       CHECK(tester != nullptr);
0152 
0153       t.callAlloc(1, 1);
0154       CHECK(2 == s_calls);
0155 
0156       t.callDealloc(1);
0157       CHECK(3 == s_calls);
0158 
0159       t.reg_.deregisterMonitor(tester);
0160       CHECK(4 == s_calls);
0161     }
0162     CHECK(4 == s_calls);
0163     CHECK(s_stopped == true);
0164     s_started = false;
0165     s_stopped = false;
0166     s_calls = 0;
0167   }
0168   SECTION("System calling system") {
0169     CHECK(0 == s_calls);
0170     CHECK(s_started == false);
0171     CHECK(s_stopped == false);
0172     {
0173       AllocTester t;
0174       CHECK(s_started == false);
0175       CHECK(s_stopped == false);
0176 
0177       auto tester = t.reg_.createAndRegisterMonitor<TestCallMonitor>(1);
0178       CHECK(s_started == true);
0179       CHECK(s_stopped == false);
0180       CHECK(1 == s_calls);
0181       CHECK(tester != nullptr);
0182 
0183       t.callAlloc(1, 1, [&t]() {
0184         t.callAlloc(1, 1);
0185         return reinterpret_cast<void*>(1);
0186       });
0187       CHECK(2 == s_calls);
0188 
0189       t.callDealloc(1, [&t](auto) { t.callDealloc(1); });
0190       CHECK(3 == s_calls);
0191 
0192       t.reg_.deregisterMonitor(tester);
0193       CHECK(4 == s_calls);
0194     }
0195     CHECK(4 == s_calls);
0196     CHECK(s_stopped == true);
0197     s_started = false;
0198     s_stopped = false;
0199     s_calls = 0;
0200   }
0201 }