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 }
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 }
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 }