From b63f31d0e00df5f04fca5a9d73e9a7b842823153 Mon Sep 17 00:00:00 2001 From: Alexey Rybalchenko Date: Tue, 11 Aug 2020 12:18:01 +0200 Subject: [PATCH] Shm: Provide debug infos only in debug mode --- CMakeLists.txt | 8 ++++++++ fairmq/CMakeLists.txt | 6 ++++++ fairmq/shmem/Common.h | 4 ++++ fairmq/shmem/Manager.h | 10 ++++++++++ fairmq/shmem/Message.h | 4 ++++ fairmq/shmem/Monitor.cxx | 24 ++++++++++++++++++++++-- 6 files changed, 54 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e2edb0e1..5bd2f8d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,8 @@ fairmq_build_option(FAST_BUILD "Fast production build. Not recommended DEFAULT OFF) fairmq_build_option(USE_EXTERNAL_GTEST "Do not use bundled GTest. Not recommended." DEFAULT OFF) +fairmq_build_option(FAIRMQ_DEBUG_MODE "Compile in debug mode (may decrease performance)." + DEFAULT OFF) ################################################################################ @@ -429,4 +431,10 @@ message(STATUS " ${Cyan}INSTALL PREFIX${CR} ${BGreen}${CMAKE_INSTALL_PREFIX message(STATUS " ") message(STATUS " ${Cyan}RUN STATIC ANALYSIS ${static_ana_summary}") message(STATUS " ") +if(FAIRMQ_DEBUG_MODE) + message(STATUS " ${Cyan}DEBUG_MODE${CR} ${BGreen}${FAIRMQ_DEBUG_MODE}${CR} (disable with ${BMagenta}-DFAIRMQ_DEBUG_MODE=OFF${CR})") +else() + message(STATUS " ${Cyan}DEBUG_MODE${CR} ${BRed}${FAIRMQ_DEBUG_MODE}${CR} (enable with ${BMagenta}-DFAIRMQ_DEBUG_MODE=ON${CR})") +endif() +message(STATUS " ") ################################################################################ diff --git a/fairmq/CMakeLists.txt b/fairmq/CMakeLists.txt index 689b8af1..a3cfb810 100644 --- a/fairmq/CMakeLists.txt +++ b/fairmq/CMakeLists.txt @@ -278,6 +278,9 @@ if(BUILD_FAIRMQ) # preprocessor definitions # ############################ target_compile_definitions(${_target} PUBLIC BOOST_ERROR_CODE_HEADER_ONLY) + if(FAIRMQ_DEBUG_MODE) + target_compile_definitions(${_target} PUBLIC FAIRMQ_DEBUG_MODE) + endif() if(BUILD_OFI_TRANSPORT) target_compile_definitions(${_target} PRIVATE BUILD_OFI_TRANSPORT) endif() @@ -374,6 +377,9 @@ if(BUILD_FAIRMQ) add_executable(fairmq-shmmonitor shmem/Monitor.cxx shmem/Monitor.h shmem/runMonitor.cxx) target_compile_definitions(fairmq-shmmonitor PUBLIC BOOST_ERROR_CODE_HEADER_ONLY) + if(FAIRMQ_DEBUG_MODE) + target_compile_definitions(fairmq-shmmonitor PUBLIC FAIRMQ_DEBUG_MODE) + endif() target_link_libraries(fairmq-shmmonitor PUBLIC Threads::Threads $<$:rt> diff --git a/fairmq/shmem/Common.h b/fairmq/shmem/Common.h index 9d67c5ac..70cfac6c 100644 --- a/fairmq/shmem/Common.h +++ b/fairmq/shmem/Common.h @@ -73,6 +73,7 @@ struct DeviceCounter std::atomic fCount; }; +#ifdef FAIRMQ_DEBUG_MODE struct MsgCounter { MsgCounter(unsigned int c) @@ -81,6 +82,7 @@ struct MsgCounter std::atomic fCount; }; +#endif struct RegionCounter { @@ -99,6 +101,7 @@ struct MetaHeader boost::interprocess::managed_shared_memory::handle_t fHandle; }; +#ifdef FAIRMQ_DEBUG_MODE struct MsgDebug { MsgDebug(pid_t pid, size_t size, const uint64_t creationTime) @@ -115,6 +118,7 @@ struct MsgDebug using Uint64MsgDebugPairAlloc = boost::interprocess::allocator, SegmentManager>; using Uint64MsgDebugHashMap = boost::unordered_map, std::equal_to, Uint64MsgDebugPairAlloc>; using Uint64MsgDebugMap = boost::interprocess::map, Uint64MsgDebugPairAlloc>; +#endif struct RegionBlock { diff --git a/fairmq/shmem/Manager.h b/fairmq/shmem/Manager.h index 25c734ff..a5a829f6 100644 --- a/fairmq/shmem/Manager.h +++ b/fairmq/shmem/Manager.h @@ -80,8 +80,10 @@ class Manager , fRegionInfos(nullptr) , fInterrupted(false) , fMsgCounter(0) +#ifdef FAIRMQ_DEBUG_MODE , fMsgDebug(nullptr) , fShmMsgCounter(nullptr) +#endif , fHeartbeatThread() , fSendHeartbeats(true) , fThrowOnBadAlloc(true) @@ -119,7 +121,9 @@ class Manager } fRegionInfos = fManagementSegment.find_or_construct(unique_instance)(fShmVoidAlloc); +#ifdef FAIRMQ_DEBUG_MODE fMsgDebug = fManagementSegment.find_or_construct(unique_instance)(fShmVoidAlloc); +#endif // store info about the managed segment as region with id 0 fRegionInfos->emplace(0, RegionInfo("", 0, 0, fShmVoidAlloc)); @@ -137,6 +141,7 @@ class Manager LOG(debug) << "initialized device counter with: " << fDeviceCounter->fCount; } +#ifdef FAIRMQ_DEBUG_MODE fShmMsgCounter = fManagementSegment.find(unique_instance).first; if (fShmMsgCounter) { @@ -146,6 +151,7 @@ class Manager fShmMsgCounter = fManagementSegment.construct(unique_instance)(0); LOG(debug) << "initialized message counter with: " << fShmMsgCounter->fCount; } +#endif fHeartbeatThread = std::thread(&Manager::SendHeartbeats, this); } @@ -407,6 +413,7 @@ class Manager void IncrementMsgCounter() { fMsgCounter.fetch_add(1, std::memory_order_relaxed); } void DecrementMsgCounter() { fMsgCounter.fetch_sub(1, std::memory_order_relaxed); } +#ifdef FAIRMQ_DEBUG_MODE void IncrementShmMsgCounter() { ++(fShmMsgCounter->fCount); } void DecrementShmMsgCounter() { --(fShmMsgCounter->fCount); } @@ -419,6 +426,7 @@ class Manager { fMsgDebug->erase(handle); } +#endif boost::interprocess::named_mutex& GetMtx() { return fShmMtx; } @@ -501,8 +509,10 @@ class Manager std::atomic fInterrupted; std::atomic fMsgCounter; // TODO: find a better lifetime solution instead of the counter +#ifdef FAIRMQ_DEBUG_MODE Uint64MsgDebugMap* fMsgDebug; MsgCounter* fShmMsgCounter; +#endif std::thread fHeartbeatThread; bool fSendHeartbeats; diff --git a/fairmq/shmem/Message.h b/fairmq/shmem/Message.h index 37897f0c..4998f1ff 100644 --- a/fairmq/shmem/Message.h +++ b/fairmq/shmem/Message.h @@ -277,9 +277,11 @@ class Message final : public fair::mq::Message } } fMeta.fHandle = fManager.Segment().get_handle_from_address(fLocalPtr); +#ifdef FAIRMQ_DEBUG_MODE boost::interprocess::scoped_lock lock(fManager.GetMtx()); fManager.IncrementShmMsgCounter(); fManager.AddMsgDebug(getpid(), size, static_cast(fMeta.fHandle), std::chrono::system_clock::now().time_since_epoch().count()); +#endif } fMeta.fSize = size; @@ -291,9 +293,11 @@ class Message final : public fair::mq::Message if (fMeta.fHandle >= 0 && !fQueued) { if (fMeta.fRegionId == 0) { fManager.Segment().deallocate(fManager.Segment().get_address_from_handle(fMeta.fHandle)); +#ifdef FAIRMQ_DEBUG_MODE boost::interprocess::scoped_lock lock(fManager.GetMtx()); fManager.DecrementShmMsgCounter(); fManager.RemoveMsgDebug(fMeta.fHandle); +#endif fMeta.fHandle = -1; } else { if (!fRegionPtr) { diff --git a/fairmq/shmem/Monitor.cxx b/fairmq/shmem/Monitor.cxx index 5b62bbf2..4624aa1e 100644 --- a/fairmq/shmem/Monitor.cxx +++ b/fairmq/shmem/Monitor.cxx @@ -287,17 +287,21 @@ void Monitor::CheckSegment() fSeenOnce = true; unsigned int numDevices = 0; +#ifdef FAIRMQ_DEBUG_MODE unsigned int numMessages = 0; +#endif if (fInteractive || fViewOnly) { DeviceCounter* dc = managementSegment.find(bipc::unique_instance).first; if (dc) { numDevices = dc->fCount; } +#ifdef FAIRMQ_DEBUG_MODE MsgCounter* mc = managementSegment.find(bipc::unique_instance).first; if (mc) { numMessages = mc->fCount; } +#endif } auto now = chrono::high_resolution_clock::now(); @@ -319,7 +323,11 @@ void Monitor::CheckSegment() << setw(10) << segment.get_size() << " | " << setw(10) << segment.get_free_memory() << " | " << setw(8) << numDevices << " | " +#ifdef FAIRMQ_DEBUG_MODE << setw(8) << numMessages << " | " +#else + << setw(8) << "nodebug" << " | " +#endif << setw(10) << (fViewOnly ? "view only" : to_string(duration)) << " |" << c << flush; } else if (fViewOnly) { @@ -332,7 +340,11 @@ void Monitor::CheckSegment() LOGV(info, user1) << "[" << fSegmentName << "] devices: " << numDevices << ", total: " << total +#ifdef FAIRMQ_DEBUG_MODE << ", msgs: " << numMessages +#else + << ", msgs: NODEBUG" +#endif << ", free: " << free << ", used: " << used; // << "\n " @@ -375,8 +387,9 @@ void Monitor::CheckSegment() } } -void Monitor::PrintDebug(const ShmId& shmId) +void Monitor::PrintDebug(const ShmId& shmId __attribute__((unused))) { +#ifdef FAIRMQ_DEBUG_MODE string managementSegmentName("fmq_" + shmId.shmId + "_mng"); try { bipc::managed_shared_memory managementSegment(bipc::open_only, managementSegmentName.c_str()); @@ -402,6 +415,9 @@ void Monitor::PrintDebug(const ShmId& shmId) } catch (bie&) { cout << "no segment found" << endl; } +#else + cout << "FairMQ was not compiled in debug mode (FAIRMQ_DEBUG_MODE)" << endl; +#endif } void Monitor::PrintQueues() @@ -456,7 +472,11 @@ void Monitor::PrintHeader() void Monitor::PrintHelp() { - cout << "controls: [x] close memory, [p] print queues, [] print a list of allocated messages, [h] help, [q] quit." << endl; + cout << "controls: [x] close memory, " + << "[p] print queues, " + << "[b] print a list of allocated messages (only available when compiled with FAIMQ_DEBUG_MODE=ON), " + << "[h] help, " + << "[q] quit." << endl; } void Monitor::RemoveObject(const string& name)