From e4fcabed1361c4cf29c52ee40e068b613a9ea0b0 Mon Sep 17 00:00:00 2001 From: Walter Lampl <Walter.Lampl@cern.ch> Date: Tue, 9 Feb 2021 19:46:13 +0100 Subject: [PATCH 1/2] IOVSvc/CBnode.h: Make instance counter atomic --- Control/IOVSvc/src/CBNode.cxx | 2 +- Control/IOVSvc/src/CBNode.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Control/IOVSvc/src/CBNode.cxx b/Control/IOVSvc/src/CBNode.cxx index fe6799283a04..8bb8683959dc 100755 --- a/Control/IOVSvc/src/CBNode.cxx +++ b/Control/IOVSvc/src/CBNode.cxx @@ -17,7 +17,7 @@ #include "SGTools/DataProxy.h" -unsigned int CBNode::s_serial = 0; +std::atomic<unsigned int> CBNode::s_serial = 0; CBNode::CBNode(const std::string& name, CBNode* parent): m_name(name), m_proxy(0), m_fcn(0), m_trig(false), m_flag(false) { diff --git a/Control/IOVSvc/src/CBNode.h b/Control/IOVSvc/src/CBNode.h index 4a5f1781c17d..d0d751257fe0 100644 --- a/Control/IOVSvc/src/CBNode.h +++ b/Control/IOVSvc/src/CBNode.h @@ -21,6 +21,7 @@ #include "AthenaKernel/IOVSvcDefs.h" #include "SGTools/CallBackID.h" +#include <atomic> namespace SG { class DataProxy; @@ -99,7 +100,7 @@ private: bool m_flag; unsigned int m_serial; - static unsigned int s_serial; + static std::atomic<unsigned int> s_serial; }; #endif -- GitLab From 3f00615bdda5f447d896c3308248b9c39bbcadd1 Mon Sep 17 00:00:00 2001 From: Walter Lampl <Walter.Lampl@cern.ch> Date: Tue, 9 Feb 2021 19:47:09 +0100 Subject: [PATCH 2/2] attempt to make IOVSvcTool::handle(inc) vaguely re-entrant --- Control/IOVSvc/IOVSvc/IIOVSvcTool.h | 3 +- Control/IOVSvc/src/IOVSvc.cxx | 16 +++- Control/IOVSvc/src/IOVSvcTool.cxx | 110 ++++++++++++++-------------- Control/IOVSvc/src/IOVSvcTool.h | 21 +++--- 4 files changed, 84 insertions(+), 66 deletions(-) diff --git a/Control/IOVSvc/IOVSvc/IIOVSvcTool.h b/Control/IOVSvc/IOVSvc/IIOVSvcTool.h index e4401e79010f..2b4326287971 100644 --- a/Control/IOVSvc/IOVSvc/IIOVSvcTool.h +++ b/Control/IOVSvc/IOVSvc/IIOVSvcTool.h @@ -69,7 +69,8 @@ public: // Get IOVRange from db for current event virtual StatusCode getRangeFromDB(const CLID& clid, const std::string& key, IOVRange& range, std::string &tag, - std::unique_ptr<IOpaqueAddress>& ioa) const = 0; + std::unique_ptr<IOpaqueAddress>& ioa, + const IOVTime& curTime) const = 0; // Get IOVRange from db for a particular event virtual StatusCode getRangeFromDB(const CLID& clid, const std::string& key, diff --git a/Control/IOVSvc/src/IOVSvc.cxx b/Control/IOVSvc/src/IOVSvc.cxx index e968fe7af849..ab11b1f1315a 100755 --- a/Control/IOVSvc/src/IOVSvc.cxx +++ b/Control/IOVSvc/src/IOVSvc.cxx @@ -406,7 +406,7 @@ IOVSvc::getRange(const CLID& clid, const std::string& key, StatusCode IOVSvc::getRangeFromDB(const CLID& clid, const std::string& key, IOVRange& range, std::string& tag, - std::unique_ptr<IOpaqueAddress>& ioa) const { + std::unique_ptr<IOpaqueAddress>& ioa) const { std::lock_guard<std::recursive_mutex> lock(m_lock); @@ -416,7 +416,19 @@ IOVSvc::getRangeFromDB(const CLID& clid, const std::string& key, << fullProxyName(clid,key) << " not registered" ); return StatusCode::FAILURE; } else { - return ist->getRangeFromDB( clid, key, range, tag, ioa ); + + //Get current time form thread-local context + const EventContext& context = Gaudi::Hive::currentContext(); + const EventIDBase& eventID = context.eventID(); + uint32_t event = eventID.lumi_block(); + uint32_t run = eventID.run_number(); + IOVTime curTime; + curTime.setRunEvent(run,event); + // get ns timestamp from event + curTime.setTimestamp(1000000000L*(uint64_t)eventID.time_stamp() + eventID.time_stamp_ns_offset()); + + + return ist->getRangeFromDB( clid, key, range, tag, ioa, curTime ); } } diff --git a/Control/IOVSvc/src/IOVSvcTool.cxx b/Control/IOVSvc/src/IOVSvcTool.cxx index 3262ad00c508..b6a0deffe7ac 100644 --- a/Control/IOVSvc/src/IOVSvcTool.cxx +++ b/Control/IOVSvc/src/IOVSvcTool.cxx @@ -227,9 +227,9 @@ IOVSvcTool::initialize() { void IOVSvcTool::handle(const Incident &inc) { - uint32_t event, run; - - std::string objname; + //The first part of the handle-function is non-const and not re-entrant + //In MT mode, only called during the serial part at the beginning of the job + //(hopefully) const bool first = m_first; if (m_first) m_first = false; @@ -253,9 +253,9 @@ IOVSvcTool::handle(const Incident &inc) { ATH_MSG_DEBUG("will ignore resetting proxy " << fullProxyName(proxy)); } } - } + }//end first + - set< DataProxy*, SortDPptr > proxiesToReset; // Forcing IOV checks on the first event in the run for AthenaMP (ATEAM-439) if(Gaudi::Concurrency::ConcurrencyFlags::numProcs()==0) { @@ -271,25 +271,26 @@ IOVSvcTool::handle(const Incident &inc) { } } + set< DataProxy*, SortDPptr > proxiesToReset; if ( inc.type() == m_checkTrigger || inc.type() == IncidentType::BeginRun ) { const EventContext& context = inc.context(); - m_curTime.reset(); + IOVTime curTime; const EventIDBase& eventID = context.eventID(); - event = eventID.lumi_block(); - run = eventID.run_number(); + uint32_t event = eventID.lumi_block(); + uint32_t run = eventID.run_number(); ATH_MSG_DEBUG("Got event info: " << "run="<< run << ", event=" << event); - m_curTime.setRunEvent(run,event); + curTime.setRunEvent(run,event); // get ns timestamp from event - m_curTime.setTimestamp(1000000000L*(uint64_t)eventID.time_stamp() + eventID.time_stamp_ns_offset()); + curTime.setTimestamp(1000000000L*(uint64_t)eventID.time_stamp() + eventID.time_stamp_ns_offset()); if (msgLvl(MSG::DEBUG)) { msg().setColor(MSG::YELLOW,MSG::RED); - msg() << inc.type() << ": [R/LB] = " << m_curTime << endmsg; + msg() << inc.type() << ": [R/LB] = " << curTime << endmsg; } if (inc.type() == IncidentType::BeginRun) { @@ -299,14 +300,14 @@ IOVSvcTool::handle(const Incident &inc) { ATH_MSG_DEBUG("Unable to get the IOVDbSvc"); return; } - if (StatusCode::SUCCESS != iovDB->signalBeginRun(m_curTime, + if (StatusCode::SUCCESS != iovDB->signalBeginRun(curTime, inc.context())) { ATH_MSG_ERROR("Unable to signal begin run to IOVDbSvc"); return; } else { - ATH_MSG_DEBUG("Signaled begin run to IOVDbSvc " << m_curTime); + ATH_MSG_DEBUG("Signaled begin run to IOVDbSvc " << curTime); } } @@ -343,9 +344,9 @@ IOVSvcTool::handle(const Incident &inc) { IIOVDbSvc *iovDB = nullptr; if (service("IOVDbSvc", iovDB, false).isSuccess()) { iovDB->signalEndProxyPreload(); - ATH_MSG_DEBUG("Signaled end proxy preload to IOVDbSvc " << m_curTime); + ATH_MSG_DEBUG("Signaled end proxy preload to IOVDbSvc " << curTime); } - } + }// end if first // If preLoadData has been set, never check validity of data again. if (m_preLoadData && m_checkOnce) { @@ -376,18 +377,18 @@ IOVSvcTool::handle(const Incident &inc) { if (msgLvl(MSG::VERBOSE)) { std::set< const SG::DataProxy* >::const_iterator pit; for (SG::DataProxy* p : m_proxies) { - msg() << " " << m_names[p] << std::endl; + msg() << " " << m_names.at(p) << std::endl; } msg() << endmsg; } proxiesToReset = m_proxies; m_triggered = false; } else { - scanStartSet(m_startSet_Clock,"(ClockTime)",proxiesToReset); - scanStartSet(m_startSet_RE,"(R/E)",proxiesToReset); + scanStartSet(m_startSet_Clock,"(ClockTime)",proxiesToReset,curTime); + scanStartSet(m_startSet_RE,"(R/E)",proxiesToReset,curTime); - scanStopSet(m_stopSet_Clock,"(ClockTime)",proxiesToReset); - scanStopSet(m_stopSet_RE,"(R/E)",proxiesToReset); + scanStopSet(m_stopSet_Clock,"(ClockTime)",proxiesToReset,curTime); + scanStopSet(m_stopSet_RE,"(R/E)",proxiesToReset,curTime); } for (auto p : m_ignoredProxies) { @@ -413,7 +414,7 @@ IOVSvcTool::handle(const Incident &inc) { //// // for (DataProxy* prx : proxiesToReset) { - ATH_MSG_VERBOSE("clearing proxy payload for " << m_names[prx]); + ATH_MSG_VERBOSE("clearing proxy payload for " << m_names.at(prx)); // Reset proxy except when one wants to reset callbacks @@ -429,9 +430,9 @@ IOVSvcTool::handle(const Incident &inc) { m_preLoadData ) { ATH_MSG_VERBOSE("preloading data"); - Gaudi::Guards::AuditorGuard auditor(m_names[prx], auditorSvc(), "preLoadProxy"); + Gaudi::Guards::AuditorGuard auditor(m_names.at(prx), auditorSvc(), "preLoadProxy"); if (prx->accessData() == nullptr) { - ATH_MSG_ERROR("problems preloading data for " << m_names[prx]); + ATH_MSG_ERROR("problems preloading data for " << m_names.at(prx)); } } @@ -460,15 +461,16 @@ IOVSvcTool::handle(const Incident &inc) { if (node->trigger()) { BFCN *ff = node->fcn(); - auditorSvc()->before("Callback",m_fcnMap[ff].name()); + auditorSvc()->before("Callback",m_fcnMap.at(ff).name()); if ((*ff)(i,resetKeys[ff]).isFailure()) { - auditorSvc()->after("Callback",m_fcnMap[ff].name()); - ATH_MSG_ERROR("Problems calling " << m_fcnMap[ff].name() + auditorSvc()->after("Callback",m_fcnMap.at(ff).name()); + ATH_MSG_ERROR("Problems calling " << m_fcnMap.at(ff).name() << std::endl << "Skipping all subsequent callbacks."); // this will cause a mem leak, but I don't care - perr = new IOVCallbackError(m_fcnMap[ff].name()); - break; } - auditorSvc()->after("Callback",m_fcnMap[ff].name()); + perr = new IOVCallbackError(m_fcnMap.at(ff).name()); + break; + } + auditorSvc()->after("Callback",m_fcnMap.at(ff).name()); } } @@ -496,10 +498,10 @@ IOVSvcTool::handle(const Incident &inc) { std::map<const DataProxy*, IOVEntry*>::iterator pitr; for (DataProxy* prx : proxiesToReset) { pitr = m_entries.find( prx ); - if ( pitr != m_entries.end() && pitr->second->range()->isInRange(m_curTime) ) { - ATH_MSG_VERBOSE("range still valid for " << m_names[prx]); + if ( pitr != m_entries.end() && pitr->second->range()->isInRange(curTime) ) { + ATH_MSG_VERBOSE("range still valid for " << m_names.at(prx)); } else { - ATH_MSG_DEBUG("calling provider()->udpateAddress(TAD) for " << m_names[prx] ); + ATH_MSG_DEBUG("calling provider()->udpateAddress(TAD) for " << m_names.at(prx) ); if (!prx->updateAddress()) { ATH_MSG_ERROR("handle: Could not update address"); if (perr != nullptr) throw (*perr); @@ -870,10 +872,11 @@ IOVSvcTool::getRange(const CLID& clid, const std::string& key, StatusCode IOVSvcTool::getRangeFromDB(const CLID& clid, const std::string& key, IOVRange& range, std::string &tag, - std::unique_ptr<IOpaqueAddress>& ioa) const { + std::unique_ptr<IOpaqueAddress>& ioa, + const IOVTime& curTime) const { - if (m_curTime.isValid()) { - return getRangeFromDB(clid, key, m_curTime, range, tag, ioa); + if (curTime.isValid()) { + return getRangeFromDB(clid, key, curTime, range, tag, ioa); } else { ATH_MSG_ERROR("Current Event not defined"); return StatusCode::FAILURE; @@ -1098,14 +1101,14 @@ IOVSvcTool::triggerCallback( const SG::DataProxy *dp, /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void -IOVSvcTool::PrintStartSet() { +IOVSvcTool::PrintStartSet() const { startITR start_itr; std::string objname; if (m_startSet_Clock.begin() != m_startSet_Clock.end()) { msg() << endl << "ClockTime start set: " << endl; for (start_itr = m_startSet_Clock.begin(); start_itr!=m_startSet_Clock.end(); ++start_itr ) { - objname = m_names[ (*start_itr)->proxy() ]; + objname = m_names.at( (*start_itr)->proxy() ); msg() << " " << objname << " (" << (*start_itr)->proxy() << ") " << (*start_itr)->range()->start() << endl; } @@ -1115,7 +1118,7 @@ IOVSvcTool::PrintStartSet() { if (m_startSet_RE.begin() != m_startSet_RE.end()) { msg() << "Run/Event start set: " << endl; for (start_itr = m_startSet_RE.begin(); start_itr!=m_startSet_RE.end();++start_itr ) { - objname = m_names[ (*start_itr)->proxy() ]; + objname = m_names.at( (*start_itr)->proxy() ); msg() << " " << objname << " (" << (*start_itr)->proxy() << ") " << (*start_itr)->range()->start() << endl; } @@ -1126,14 +1129,14 @@ IOVSvcTool::PrintStartSet() { /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void -IOVSvcTool::PrintStopSet() { +IOVSvcTool::PrintStopSet() const { stopITR stop_itr; std::string objname; if (m_stopSet_Clock.begin() != m_stopSet_Clock.end()) { msg() << endl << "ClockTime stop set: " << endl; for( stop_itr=m_stopSet_Clock.begin(); stop_itr!=m_stopSet_Clock.end(); ++stop_itr ) { - objname = m_names[ (*stop_itr)->proxy() ]; + objname = m_names.at((*stop_itr)->proxy()); msg() << " " << objname << " (" << (*stop_itr)->proxy() << ") " << (*stop_itr)->range()->stop() << endl; } @@ -1143,7 +1146,7 @@ IOVSvcTool::PrintStopSet() { if (m_stopSet_RE.begin() != m_stopSet_RE.end()) { msg() << "Run/Event stop set: " << endl; for( stop_itr=m_stopSet_RE.begin(); stop_itr!=m_stopSet_RE.end(); ++stop_itr ) { - objname = m_names[ (*stop_itr)->proxy() ]; + objname = m_names.at((*stop_itr)->proxy()); msg() << " " << objname << " (" << (*stop_itr)->proxy() << ") " << (*stop_itr)->range()->stop() << endl; } @@ -1153,7 +1156,7 @@ IOVSvcTool::PrintStopSet() { /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void -IOVSvcTool::PrintProxyMap(){ +IOVSvcTool::PrintProxyMap() const{ msg() << endl; msg() << "------------------------------ IOVSvc Proxy Map " << "------------------------------" << endl; @@ -1168,18 +1171,15 @@ IOVSvcTool::PrintProxyMap(){ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void -IOVSvcTool::PrintProxyMap(const SG::DataProxy* dp){ +IOVSvcTool::PrintProxyMap(const SG::DataProxy* dp) const { msg() << " " << dp << " " << dp->clID() << " " << m_names.find(dp)->second << endl; - - pair<pmITR,pmITR> pi = m_proxyMap.equal_range(dp); - pmITR pitr; - + auto pi = m_proxyMap.equal_range(dp); if (pi.first == pi.second) { msg() << " -> no callback associated" << endl; } else { - for (pitr=pi.first; pitr!=pi.second; ++pitr) { + for (auto pitr=pi.first; pitr!=pi.second; ++pitr) { BFCN* fcn = pitr->second; map<BFCN*,CallBackID>::const_iterator fitr = m_fcnMap.find(fcn); CallBackID cbid = fitr->second; @@ -1445,7 +1445,8 @@ IOVSvcTool::reinitialize(){ void IOVSvcTool::scanStartSet(startSet &pSet, const std::string &type, - std::set<SG::DataProxy*, SortDPptr> &proxiesToReset) { + std::set<SG::DataProxy*, SortDPptr> &proxiesToReset, + const IOVTime& curTime) const { std::string objname; @@ -1458,9 +1459,9 @@ IOVSvcTool::scanStartSet(startSet &pSet, const std::string &type, startITR start_itr( pSet.begin() ); while ( start_itr != pSet.end() ) { - if (m_resetAllCallbacks || (*start_itr)->range()->start() > m_curTime) { + if (m_resetAllCallbacks || (*start_itr)->range()->start() > curTime) { if (msgLvl(MSG::DEBUG)) { - msg() << "\t" << m_names[ (*start_itr)->proxy() ] << ": " + msg() << "\t" << m_names.at((*start_itr)->proxy()) << ": " << (*start_itr)->range()->start()<<" <- removed"<<endl; } proxiesToReset.insert( (*start_itr)->proxy() ); @@ -1483,7 +1484,8 @@ IOVSvcTool::scanStartSet(startSet &pSet, const std::string &type, void IOVSvcTool::scanStopSet(stopSet &pSet, const std::string &type, - std::set<SG::DataProxy*, SortDPptr> &proxiesToReset) { + std::set<SG::DataProxy*, SortDPptr> &proxiesToReset, + const IOVTime& curTime) const { std::string objname; @@ -1495,9 +1497,9 @@ IOVSvcTool::scanStopSet(stopSet &pSet, const std::string &type, stopITR stop_itr(pSet.begin()); while ( stop_itr != pSet.end() ) { - if (m_resetAllCallbacks || (*stop_itr)->range()->stop() <= m_curTime) { + if (m_resetAllCallbacks || (*stop_itr)->range()->stop() <= curTime) { if (msgLvl(MSG::DEBUG)) { - msg() << " " << m_names[ (*stop_itr)->proxy() ] << ": " + msg() << " " << m_names.at((*stop_itr)->proxy()) << ": " << (*stop_itr)->range()->stop()<< " -> removed"<<endl; } proxiesToReset.insert( (*stop_itr)->proxy() ); diff --git a/Control/IOVSvc/src/IOVSvcTool.h b/Control/IOVSvc/src/IOVSvcTool.h index 7b7bfd4ddb61..c61d2d0b6358 100644 --- a/Control/IOVSvc/src/IOVSvcTool.h +++ b/Control/IOVSvc/src/IOVSvcTool.h @@ -125,7 +125,8 @@ public: // Get IOVRange from db for current event virtual StatusCode getRangeFromDB(const CLID& clid, const std::string& key, IOVRange& range, std::string &tag, - std::unique_ptr<IOpaqueAddress>& ioa) const override; + std::unique_ptr<IOpaqueAddress>& ioa, + const IOVTime& curTime) const override; // Get IOVRange from db for a particular event virtual StatusCode getRangeFromDB(const CLID& clid, const std::string& key, @@ -187,7 +188,7 @@ private: ServiceHandle<IClassIDSvc> p_CLIDSvc; ServiceHandle<IToolSvc> p_toolSvc; - IOVTime m_curTime{0}; + //IOVTime m_curTime{0}; typedef IOVSvcCallBackFcn BFCN; typedef std::multimap<const SG::DataProxy*, BFCN*>::iterator pmITR; @@ -235,7 +236,7 @@ private: bool m_checkOnce{false}; bool m_triggered{false}; bool m_firstEventOfRun{false}; - bool m_resetAllCallbacks{false}; + bool m_resetAllCallbacks{false}; std::string m_checkTrigger; Gaudi::Property<bool> m_preLoadRanges{this, "preLoadRanges", false}; @@ -248,14 +249,16 @@ private: void scanStartSet(startSet &pSet, const std::string &type, - std::set<SG::DataProxy*, SortDPptr> &proxiesToReset); + std::set<SG::DataProxy*, SortDPptr> &proxiesToReset, + const IOVTime& curTime) const; void scanStopSet(stopSet &pSet, const std::string &type, - std::set<SG::DataProxy*, SortDPptr> &proxiesToReset); + std::set<SG::DataProxy*, SortDPptr> &proxiesToReset, + const IOVTime& curTime) const; - void PrintStartSet(); - void PrintStopSet(); - void PrintProxyMap(); - void PrintProxyMap(const SG::DataProxy*); + void PrintStartSet() const; + void PrintStopSet() const; + void PrintProxyMap() const; + void PrintProxyMap(const SG::DataProxy*) const; }; -- GitLab