Skip to content
Snippets Groups Projects
Commit f04628be authored by Christopher Rob Jones's avatar Christopher Rob Jones
Browse files

Move RICH allocation tracker to dedicated header and use in more derived conditions

parent 9dfb9a57
No related branches found
No related tags found
1 merge request!3928Add allocate/deallocate mismatch checking code to RICH derived conditions
Pipeline #5044268 passed
Showing
with 198 additions and 82 deletions
......@@ -16,6 +16,7 @@
#include "DetDesc/IConditionDerivationMgr.h"
// utils
#include "RichUtils/AllocateCount.h"
#include "RichUtils/RichSmartIDSorter.h"
// local
......@@ -123,14 +124,18 @@ namespace Rich::Detector {
// messaging
/// My name
inline static const std::string Name = "Rich::Detector::RichPDInfo";
static constexpr auto MyName() noexcept { return "Rich::Detector::RichPDInfo"; }
/// Overload ostream operator
friend inline auto& operator<<( std::ostream& s, const PDInfo& ) {
// ToDo : Print something useful here.
return s << "[ " << Name << " ]";
return s << "[ " << MyName() << " ]";
}
private:
/// Allocation tracking
Rich::AllocateCount<PDInfo> m_track_instances;
public:
// conditions handling
......@@ -142,7 +147,7 @@ namespace Rich::Detector {
const Detector::Rich2& r2 ) {
auto msgSvc = Gaudi::svcLocator()->service<IMessageSvc>( "MessageSvc" );
assert( msgSvc );
MsgStream log( msgSvc, Name );
MsgStream log( msgSvc, MyName() );
log << MSG::DEBUG << "Update triggered" << endmsg;
return PDInfo{r1, r2};
}
......
......@@ -30,6 +30,7 @@
#include "LHCbMath/SIMDTypes.h"
// Utils
#include "RichUtils/AllocateCount.h"
#include "RichUtils/RichMirrorSegPosition.h"
#include "RichUtils/RichSIMDRayTracing.h"
#include "RichUtils/RichSIMDTypes.h"
......@@ -52,10 +53,8 @@
#include <array>
#include <cassert>
#include <memory>
#include <mutex>
#include <optional>
#include <ostream>
#include <set>
#include <sstream>
#include <string>
#include <type_traits>
......@@ -675,6 +674,8 @@ namespace Rich::Detector {
using DetElem = DETELEM;
using BaseDetElem = BASEDETELEM;
using Base = details::RichBase<BASEDETELEM>;
// Shortcut to this type
using MyType = RichX<RICH, DETELEM, BASEDETELEM, RADIATOR>;
private:
/// Owned radiator object
......@@ -685,62 +686,8 @@ namespace Rich::Detector {
const auto& radiator() const noexcept { return m_rad; }
private:
// debugging memory management issues
struct AllocateCount {
private:
static constexpr auto MyName() noexcept {
return ( RICH == Rich::Rich1 ? "Rich::Detector::Rich1" : //
RICH == Rich::Rich2 ? "Rich::Detector::Rich2" : "UNDEFINED" );
}
auto& msg() const {
static std::once_flag run_once;
static std::optional<MsgStream> msg;
std::call_once( run_once, [&]() {
auto msgSvc = Gaudi::svcLocator()->service<IMessageSvc>( "MessageSvc" );
assert( msgSvc );
msg.emplace( msgSvc, MyName() );
} );
return msg.value();
}
public:
AllocateCount() { track( "Defl construct", this ); }
AllocateCount( const AllocateCount& from ) { track( "Copy construct", this, &from ); }
AllocateCount( AllocateCount&& from ) { track( "Move construct", this, &from ); }
AllocateCount& operator=( const AllocateCount& from ) { track( "Copy assign ", this, &from ); }
AllocateCount& operator=( AllocateCount&& from ) { track( "Move assign ", this, &from ); }
~AllocateCount() { untrack( this ); }
private:
struct Instances : public std::set<const AllocateCount*> {
using std::set<const AllocateCount*>::set;
~Instances() {
if ( !this->empty() ) {
std::cerr << "Rich::Detector::" << RICH << "::AllocateCount ERROR Still " << this->size()
<< " allocated dervived condition objects !!" << std::endl;
}
}
};
static auto& instances() {
static Instances v;
return v;
}
static void track( const std::string op, const AllocateCount* p, const AllocateCount* from = nullptr ) {
static std::mutex insert_lock;
std::scoped_lock{insert_lock};
instances().insert( p );
p->msg() << MSG::VERBOSE << op << " " << p;
if ( from ) { p->msg() << " (from " << from << ")"; }
p->msg() << " : " << instances().size() << " active objects" << endmsg;
}
static void untrack( const AllocateCount* p ) {
static std::mutex erase_lock;
std::scoped_lock{erase_lock};
instances().erase( p );
p->msg() << MSG::VERBOSE << "Destructed " << p << " : " << instances().size() << " active objects" << endmsg;
}
};
AllocateCount m_track_instances;
/// Allocation tracking
AllocateCount<MyType> m_track_instances;
public:
// constructors
......@@ -750,7 +697,7 @@ namespace Rich::Detector {
: details::RichBase<BASEDETELEM>( deRich ) //
, m_rad( deRich.radiatorGas() ) {}
private:
public:
// messaging
/// name string
......@@ -759,18 +706,15 @@ namespace Rich::Detector {
RICH == Rich::Rich2 ? "Rich::Detector::Rich2" : "UNDEFINED" );
}
public:
// messaging
/// Overload ostream operator
friend inline auto& operator<<( MsgStream& s, const RichX<RICH, DETELEM, BASEDETELEM, RADIATOR>& r ) {
friend inline auto& operator<<( MsgStream& s, const MyType& r ) {
s << MyName() << " ";
r.fillStream( s );
return s << " " << r.radiator();
}
/// Overload ostream operator
friend inline auto& operator<<( std::ostream& s, const RichX<RICH, DETELEM, BASEDETELEM, RADIATOR>& r ) {
friend inline auto& operator<<( std::ostream& s, const MyType& r ) {
s << MyName() << " ";
r.fillStream( s );
return s << " " << r.radiator();
......
......@@ -30,6 +30,7 @@
#endif
// RICH Utils
#include "RichUtils/AllocateCount.h"
#include "RichUtils/RichDAQDefinitions.h"
// Detectors
......@@ -181,6 +182,9 @@ namespace Rich::Future::DAQ {
public:
// accessors
/// name string
static constexpr auto MyName() noexcept { return "Rich::Future::DAQ::PDMDBDecodeMapping"; }
/// mapping version
inline auto version() const noexcept { return m_mappingVer; }
......@@ -281,6 +285,10 @@ namespace Rich::Future::DAQ {
/// Pointer back to parent algorithm (for messaging)
const Gaudi::Algorithm* m_parent{nullptr};
private:
/// Allocation tracking
Rich::AllocateCount<PDMDBDecodeMapping> m_track_instances;
};
} // namespace Rich::Future::DAQ
......@@ -32,6 +32,7 @@
#include "RichDetectors/Utilities.h"
// RICH Utils
#include "RichUtils/AllocateCount.h"
#include "RichUtils/RichDAQDefinitions.h"
// STL
......@@ -153,6 +154,9 @@ namespace Rich::Future::DAQ {
public:
// accessors
/// name string
static constexpr auto MyName() noexcept { return "Rich::Future::DAQ::PDMDBEncodeMapping"; }
/// mapping version
auto version() const noexcept { return m_mappingVer; }
......@@ -263,6 +267,10 @@ namespace Rich::Future::DAQ {
/// Pointer back to parent algorithm (for messaging)
const Gaudi::Algorithm* m_parent{nullptr};
private:
/// Allocation tracking
Rich::AllocateCount<PDMDBEncodeMapping> m_track_instances;
};
} // namespace Rich::Future::DAQ
......@@ -24,6 +24,7 @@
#include "boost/container/static_vector.hpp"
// RICH Utils
#include "RichUtils/AllocateCount.h"
#include "RichUtils/RichDAQDefinitions.h"
#ifndef USE_DD4HEP
......@@ -218,6 +219,9 @@ namespace Rich::Future::DAQ {
/// mapping version
inline auto version() const noexcept { return m_mappingVer; }
/// name string
static constexpr auto MyName() noexcept { return "Rich::Future::DAQ::Tel40CableMapping"; }
public:
// Conditions handling
......@@ -315,6 +319,10 @@ namespace Rich::Future::DAQ {
/// Pointer back to parent algorithm (for messaging)
const Gaudi::Algorithm* m_parent{nullptr};
private:
/// Allocation tracking
Rich::AllocateCount<Tel40CableMapping> m_track_instances;
};
} // namespace Rich::Future::DAQ
......@@ -40,6 +40,9 @@
#include "RichDetectors/RichMirror.h"
#include "RichDetectors/Utilities.h"
// Utils
#include "RichUtils/AllocateCount.h"
// STL
#include <algorithm>
#include <array>
......@@ -783,13 +786,13 @@ namespace Rich::Utils {
public:
// messaging
/// My name
inline static const std::string Name = "Rich::Utils::MirrorFinder";
/// name string
static constexpr auto MyName() noexcept { return "Rich::Utils::MirrorFinder"; }
/// Overload ostream operator
friend inline auto& operator<<( std::ostream& s, const MirrorFinder& ) {
// ToDo : Print something useful here.
return s << "[ " << Name << " ]";
return s << "[ " << MyName() << " ]";
}
public:
......@@ -803,7 +806,7 @@ namespace Rich::Utils {
static auto generate( const Detector::Rich1& r1, const Detector::Rich2& r2 ) {
auto msgSvc = Gaudi::svcLocator()->service<IMessageSvc>( "MessageSvc" );
assert( msgSvc );
MsgStream log( msgSvc, Name );
MsgStream log( msgSvc, MyName() );
log << MSG::DEBUG << "Update triggered" << endmsg;
return MirrorFinder{r1, r2};
}
......@@ -830,6 +833,10 @@ namespace Rich::Utils {
std::move( key ), // output key
&generate );
}
private:
/// Allocation tracking
AllocateCount<MirrorFinder> m_track_instances;
};
} // namespace Rich::Utils
......@@ -27,6 +27,9 @@
// Det Desc
#include "DetDesc/ConditionKey.h"
// Utils
#include "RichUtils/AllocateCount.h"
// Detectors
#include "RichDetectors/Rich1.h"
#include "RichDetectors/Rich2.h"
......@@ -98,6 +101,9 @@ namespace Rich::Utils {
public:
// conditions handling
/// name string
static constexpr auto MyName() noexcept { return "Rich::Utils::RadIntersects"; }
/// Default conditions name
inline static const std::string DefaultConditionKey =
DeRichLocations::derivedCondition( "RadiatorIntersects-Handler" );
......@@ -114,7 +120,7 @@ namespace Rich::Utils {
const Detector::Rich2& r2 ) {
auto msgSvc = Gaudi::svcLocator()->service<IMessageSvc>( "MessageSvc" );
assert( msgSvc );
MsgStream log( msgSvc, "Rich::Utils::RadIntersects" );
MsgStream log( msgSvc, MyName() );
log << MSG::DEBUG << "Update triggered" << endmsg;
return RadIntersects{r1, r2};
}
......@@ -132,6 +138,10 @@ namespace Rich::Utils {
std::move( key ), //
&generate );
}
private:
/// Allocation tracking
Rich::AllocateCount<RadIntersects> m_track_instances;
};
} // namespace Rich::Utils
......@@ -26,6 +26,7 @@
#include "RichFutureUtils/RichGeomPhoton.h"
#include "RichFutureUtils/RichMirrorFinder.h"
#include "RichFutureUtils/RichSIMDMirrorData.h"
#include "RichUtils/AllocateCount.h"
#include "RichUtils/RichRayTracingUtils.h"
#include "RichUtils/RichSIMDRayTracing.h"
#include "RichUtils/RichSIMDTypes.h"
......@@ -192,18 +193,15 @@ namespace Rich::Utils {
const LHCb::RichTraceMode mode, //
const Rich::Side fSide ) const;
/// Access PD panel for RICH and side
//[[nodiscard]] decltype( auto ) pdPanel( const Rich::DetectorType rich, //
// const Rich::Side side ) const noexcept {
// return m_rich[rich]->pdPanel( side );
// }
/// Access the associated mirror finder
[[nodiscard]] const Utils::MirrorFinder& mirrorFinder() const noexcept { return *m_mirrorFinder; }
public:
// conditions handling
/// name string
static constexpr auto MyName() noexcept { return "Rich::Utils::RayTracing"; }
/// Default conditions name
inline static const std::string DefaultConditionKey = DeRichLocations::derivedCondition( "RichRayTracing-Handler" );
......@@ -220,7 +218,7 @@ namespace Rich::Utils {
const MirrorFinder& mf ) {
auto msgSvc = Gaudi::svcLocator()->service<IMessageSvc>( "MessageSvc" );
assert( msgSvc );
MsgStream log( msgSvc, "Rich::Utils::RayTracing" );
MsgStream log( msgSvc, MyName() );
log << MSG::DEBUG << "Update triggered" << endmsg;
return RayTracing{r1, r2, mf};
}
......@@ -280,6 +278,10 @@ namespace Rich::Utils {
/// Flag to control if the secondary mirrors are treated as if they are completely flat
DetectorArray<bool> m_treatSecMirrsFlat = {true, false};
}; // namespace Rich::Utils
private:
/// Allocation tracking
AllocateCount<RayTracing> m_track_instances;
};
} // namespace Rich::Utils
......@@ -31,6 +31,7 @@
#include "Kernel/RichSmartID.h"
// Utils
#include "RichUtils/AllocateCount.h"
#include "RichUtils/RichException.h"
#include "RichUtils/RichMap.h"
#include "RichUtils/RichPixelCluster.h"
......@@ -151,6 +152,9 @@ namespace Rich::Utils {
public:
// conditions handling
/// name string
static constexpr auto MyName() noexcept { return "Rich::Utils::RichSmartIDs"; }
/// Default conditions name
inline static const std::string DefaultConditionKey = DeRichLocations::derivedCondition( "RichSmartIDs-Handler" );
......@@ -160,7 +164,7 @@ namespace Rich::Utils {
const Detector::Rich2& r2 ) {
auto msgSvc = Gaudi::svcLocator()->service<IMessageSvc>( "MessageSvc" );
assert( msgSvc );
MsgStream log( msgSvc, "Rich::Utils::RichSmartIDs" );
MsgStream log( msgSvc, MyName() );
log << MSG::DEBUG << "Update triggered" << endmsg;
return RichSmartIDs{pds, r1, r2};
}
......@@ -198,6 +202,10 @@ namespace Rich::Utils {
/// Pointers to RICH1 and RICH2
Rich::DetectorArray<const Detector::RichBase*> m_riches = {{}};
private:
/// Allocation tracking
AllocateCount<RichSmartIDs> m_track_instances;
};
} // namespace Rich::Utils
......@@ -26,6 +26,7 @@
// Utils
#include "RichInterfaces/IRichParticleProperties.h"
#include "RichUtils/AllocateCount.h"
#include "RichUtils/RichTrackSegment.h"
// Det Desc
......@@ -163,6 +164,9 @@ namespace Rich::Utils {
public:
// conditions handling
/// name string
static constexpr auto MyName() noexcept { return "Rich::Utils::TabulatedRefIndex"; }
/// Default conditions name
inline static const std::string DefaultConditionKey = DeRichLocations::derivedCondition( "RichRefIndex-Handler" );
......@@ -179,7 +183,7 @@ namespace Rich::Utils {
assert( s_partProps );
auto msgSvc = Gaudi::svcLocator()->service<IMessageSvc>( "MessageSvc" );
assert( msgSvc );
MsgStream log( msgSvc, "Rich::Utils::TabulatedRefIndex" );
MsgStream log( msgSvc, MyName() );
log << MSG::DEBUG << "Update triggered" << endmsg;
return TabulatedRefIndex{rich1, // RICH1
rich2, // RICH2
......@@ -209,6 +213,10 @@ namespace Rich::Utils {
std::move( key ), // output
&generate );
}
private:
/// Allocation tracking
AllocateCount<TabulatedRefIndex> m_track_instances;
};
} // namespace Rich::Utils
/*****************************************************************************\
* (c) Copyright 2000-2022 CERN for the benefit of the LHCb Collaboration *
* *
* This software is distributed under the terms of the GNU General Public *
* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". *
* *
* In applying this licence, CERN does not waive the privileges and immunities *
* granted to it by virtue of its status as an Intergovernmental Organization *
* or submit itself to any jurisdiction. *
\*****************************************************************************/
#pragma once
// Gaudi
#include "GaudiKernel/Bootstrap.h"
#include "GaudiKernel/IMessageSvc.h"
#include "GaudiKernel/ISvcLocator.h"
#include "GaudiKernel/MsgStream.h"
#include "GaudiKernel/System.h"
// STL
#include <mutex>
#include <optional>
#include <set>
#include <string>
#include <type_traits>
namespace Rich {
/// debugging memory management issues
template <typename TYPE>
struct AllocateCount {
private:
static constexpr auto MyName() noexcept { return TYPE::MyName(); }
auto& msg() const {
static std::once_flag run_once;
static std::optional<MsgStream> msg;
std::call_once( run_once, [&]() {
auto msgSvc = Gaudi::svcLocator()->service<IMessageSvc>( "MessageSvc" );
assert( msgSvc );
msg.emplace( msgSvc, MyName() );
} );
return msg.value();
}
auto& info() const { return msg() << MSG::INFO; }
auto& warning() const { return msg() << MSG::WARNING; }
auto& debug() const { return msg() << MSG::DEBUG; }
auto& verbose() const { return msg() << MSG::VERBOSE; }
public:
AllocateCount() { track( "Construct " ); }
AllocateCount( const AllocateCount& from ) { track( "Copy construct", &from ); }
AllocateCount( AllocateCount&& from ) { track( "Move construct", &from ); }
AllocateCount& operator=( const AllocateCount& from ) {
track( "Copy assign ", &from );
return *this;
}
AllocateCount& operator=( AllocateCount&& from ) {
track( "Move assign ", &from );
return *this;
}
~AllocateCount() { untrack(); }
private:
struct Instances : public std::set<const AllocateCount*> {
using std::set<const AllocateCount*>::set;
~Instances() {
if ( !this->empty() ) {
// Do not use MessageService here as happens at very end after application has shutdown.
std::cerr << "RichAllocateCount ERROR Still " << this->size() << " allocated " << MyName()
<< " dervived condition objects !!" << std::endl;
}
}
};
private:
auto& lock() {
static std::mutex instances_lock;
return instances_lock;
}
auto& instances() {
static Instances instances;
return instances;
}
void check() {
const std::size_t max_expected_size = 10;
if ( instances().size() > max_expected_size ) {
warning() << "Unusually high number of active " << MyName() << " condition slices (" << instances().size()
<< ">" << max_expected_size << ")" << endmsg;
}
}
void track( const std::string_view op, const AllocateCount* from = nullptr ) {
std::scoped_lock{lock()};
instances().insert( this );
verbose() << op << " " << this;
if ( from ) { verbose() << " (from " << from << ")"; }
verbose() << " : Currently " << instances().size() << " active objects" << endmsg;
check();
}
void untrack() {
std::scoped_lock{lock()};
instances().erase( this );
verbose() << "Destructed " << this << " : Currently " << instances().size() << " active objects" << endmsg;
check();
}
};
} // namespace Rich
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment