Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:57:43

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