ATLAS Offline Software
SGHiveMgrSvc.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "GaudiKernel/ConcurrencyFlags.h"
8 #include "AthenaKernel/StoreID.h"
11 #include "StoreGate/SGHiveMgrSvc.h"
12 
13 using namespace SG;
14 
15 __thread HiveEventSlot* s_current(0);
16 
17 HiveMgrSvc::HiveMgrSvc(const std::string& name,
18  ISvcLocator* svc) : base_class(name, svc),
19  m_hiveStore(StoreID::storeName(StoreID::EVENT_STORE), name),
20  m_nSlots(1)
21 {
22  declareProperty("HiveStoreSvc", m_hiveStore);
23  declareProperty("NSlots", m_nSlots, "number of event slots");
24 }
25 
26 
35 void HiveMgrSvc::setNumProcs(size_t numProcs)
36 {
37  Gaudi::Concurrency::ConcurrencyFlags::setNumProcs(numProcs);
38 }
39 
47  s_current = &m_slots[slotIndex];
49  return StatusCode::SUCCESS;
50 }
51 
58  StatusCode rc(StatusCode::FAILURE);
59  if (slotIndex < m_nSlots) {
60  rc=m_slots[slotIndex].pEvtStore->clearStore();
61  if (rc.isSuccess()) debug() << "cleared store " << slotIndex << endmsg;
62  }
63  if (!rc.isSuccess()) error() << "could not clear store " << slotIndex << endmsg;
64  return rc;
65 }
66 
73  //FIXME what if running?
74  if(FSMState() == Gaudi::StateMachine::INITIALIZED) {
75  fatal() << "Too late to change the number of slots!" << endmsg;
76  return StatusCode::FAILURE;
77  } else {
78  m_slots.resize(slots);
79  m_nSlots = slots;
80  m_freeSlots.store(slots);
81  Gaudi::Concurrency::ConcurrencyFlags::setNumConcEvents( slots );
82  return StatusCode::SUCCESS;
83  }
84 }
85 
87  return m_nSlots;
88 }
89 
90 
91 
98 size_t HiveMgrSvc::allocateStore( int evtNumber ) {
99  if (m_freeSlots == 0) {
100  error() << "No slots available for event number " << evtNumber << endmsg;
101  return std::string::npos;
102  }
103  std::scoped_lock lock{m_mutex};
104  for (size_t index=0; index<m_nSlots; ++index) {
105  if( m_slots[index].eventNumber == evtNumber) {
106  error() << "Attempt to allocate an event slot for an event that is still active: event number " << evtNumber << endmsg;
107  return std::string::npos;
108  } else if (m_slots[index].eventNumber == -1) {
109  m_slots[index].eventNumber = evtNumber;
110  debug() << "Slot " << index
111  << " allocated to event number "<< evtNumber << endmsg;
112  m_freeSlots--;
113  return index;
114  }
115  }
116  error() << "No slots available for event number " << evtNumber << endmsg;
117  return std::string::npos;
118 }
119 
125 StatusCode HiveMgrSvc::freeStore( size_t slotIndex ) {
126  if (slotIndex < m_nSlots) {
127  std::scoped_lock lock{m_mutex};
128  if (m_slots[slotIndex].eventNumber == -1) {
129  debug() << "Slot " << slotIndex << " is already free" << endmsg;
130  }
131  else {
132  m_slots[slotIndex].eventNumber = -1;
133  m_freeSlots++;
134  debug() << "Freed slot " << slotIndex << endmsg;
135  }
136  return StatusCode::SUCCESS;
137  } else {
138  error() << "no slot at " << slotIndex << endmsg;
139  return StatusCode::FAILURE;
140  }
141 }
142 
143 
149 size_t HiveMgrSvc::getPartitionNumber(int evtNumber) const {
150  std::scoped_lock lock{m_mutex};
151  for (size_t index=0; index<m_nSlots; ++index) {
152  if( m_slots[index].eventNumber == evtNumber) return index;
153  }
154  return std::string::npos;
155 }
156 
158  return m_freeSlots;
159 }
160 
161 bool HiveMgrSvc::exists( const DataObjID& id) {
162  // this should only get called in error situations, so we
163  // don't care if it's slow
164  std::string key = id.key();
165  key.erase(0,key.find('+')+1);
166 
167  if (id.clid() == 0) {
168  // this is an ugly hack in case the DataObjID gets munged
169  // upstream, and we have to re-separate it into (class,key)
170  // from "class/key"
171  std::string cl = id.fullKey();
172  cl.erase(cl.find('/'),cl.length());
173 
174  DataObjID d2(std::move(cl),key);
175  return m_hiveStore->transientContains(d2.clid(), key);
176  } else {
177  return m_hiveStore->transientContains(id.clid(), key);
178  }
179 
180 }
181 
183  verbose() << "Initializing " << name() << endmsg;
184 
185  if ( !(Service::initialize().isSuccess()) ) {
186  fatal() << "Unable to initialize base class" << endmsg;
187  return StatusCode::FAILURE;
188  }
189  //this sets the hiveStore pointer to StoreGateSvc.defaultStore
190  if (!(m_hiveStore.retrieve()).isSuccess()) {
191  fatal() << "Unable to get hive event store" << endmsg;
192  return StatusCode::FAILURE;
193  }
194 
195  //use hiveStore default impl store as prototype
196  Service* child(0);
197  SGImplSvc* pSG(0);
198 
199  for( size_t i = 0; i< m_nSlots; ++i) {
200  std::ostringstream oss;
201  oss << i << '_' << m_hiveStore->currentStore()->name();
202  if (CloneService::clone(m_hiveStore->currentStore(), oss.str(), child).isSuccess() &&
203  child->initialize().isSuccess() &&
204  0 != (pSG = dynamic_cast<SGImplSvc*>(child)) )
205  {
206  pSG->setSlotNumber (i, m_nSlots);
207  m_slots.push_back(SG::HiveEventSlot(pSG));
208  } else {
209  fatal() << "Unable to clone event store " << oss.str() << endmsg;
210  return StatusCode::FAILURE;
211  }
212  }
213 
214  m_freeSlots.store( m_nSlots );
215  Gaudi::Concurrency::ConcurrencyFlags::setNumConcEvents( m_nSlots );
216 
217  return selectStore(0);
218 }
219 
221  info() << "Finalizing " << name() << endmsg;
222 
223  for (SG::HiveEventSlot& s : m_slots) {
224  // The impl services are not set to active, so ServiceManager
225  // won't finalize them.
226  CHECK( s.pEvtStore->finalize() );
227  s.pEvtStore->release();
228  }
229 
230  return StatusCode::SUCCESS;
231 }
232 
233 
235 {
236  // On a start transition, merge the string pool from the default store
237  // into that of each store, so that they will know about any explicit
238  // registrations that were done during initialize().
239  // See ATEAM-846.
240  for (SG::HiveEventSlot& slot : m_slots) {
241  slot.pEvtStore->mergeStringPool (*m_hiveStore->currentStore());
242  }
243  return StatusCode::SUCCESS;
244 }
SG::HiveEventSlot
Definition: SGHiveEventSlot.h:19
SG::HiveMgrSvc::initialize
virtual StatusCode initialize() override
Definition: SGHiveMgrSvc.cxx:182
SG::HiveMgrSvc::getPartitionNumber
virtual size_t getPartitionNumber(int eventnumber) const override
Get the slot number corresponding to a given event.
Definition: SGHiveMgrSvc.cxx:149
StoreGateSvc::setSlot
static void setSlot(SG::HiveEventSlot *pSlot)
set the hive event slot pointer: used by the event loop mgrs
Definition: StoreGateSvc.cxx:44
SG
Forward declaration.
Definition: CaloCellPacker_400_500.h:32
SG::HiveMgrSvc::m_hiveStore
ServiceHandle< StoreGateSvc > m_hiveStore
Definition: SGHiveMgrSvc.h:119
python.StoreID.EVENT_STORE
int EVENT_STORE
Definition: StoreID.py:10
index
Definition: index.py:1
initialize
void initialize()
Definition: run_EoverP.cxx:894
SG::HiveMgrSvc::finalize
virtual StatusCode finalize() override
Definition: SGHiveMgrSvc.cxx:220
SG::HiveMgrSvc::m_slots
std::vector< SG::HiveEventSlot > m_slots
Definition: SGHiveMgrSvc.h:121
python.RatesEmulationExample.lock
lock
Definition: RatesEmulationExample.py:148
SG::HiveMgrSvc::m_freeSlots
std::atomic< size_t > m_freeSlots
Definition: SGHiveMgrSvc.h:123
SGHiveMgrSvc.h
SG::HiveMgrSvc::exists
virtual bool exists(const DataObjID &) override
Check if a data object exists in store.
Definition: SGHiveMgrSvc.cxx:161
lumiFormat.i
int i
Definition: lumiFormat.py:85
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
SGImplSvc.h
SG::HiveMgrSvc::HiveMgrSvc
HiveMgrSvc(const std::string &name, ISvcLocator *svc)
Standard Service Constructor. sets active store to default event store.
Definition: SGHiveMgrSvc.cxx:17
SGImplSvc
The Athena Transient Store API.
Definition: SGImplSvc.h:109
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
StoreID
defines an enum used by address providers to decide what kind of StoreGateSvc they are providing addr...
Definition: StoreID.h:18
xAOD::eventNumber
eventNumber
Definition: EventInfo_v1.cxx:124
SG::HiveMgrSvc::start
virtual StatusCode start() override
Definition: SGHiveMgrSvc.cxx:234
Handler::svc
AthROOTErrorHandlerSvc * svc
Definition: AthROOTErrorHandlerSvc.cxx:10
CloneService.h
StoreID.h
SG::HiveMgrSvc::selectStore
virtual StatusCode selectStore(size_t slotIndex) override
Activate an given 'slot' for all subsequent calls within the same thread id.
Definition: SGHiveMgrSvc.cxx:46
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
debug
const bool debug
Definition: MakeUncertaintyPlots.cxx:53
SG::HiveMgrSvc::allocateStore
virtual size_t allocateStore(int evtnumber) override
Allocate a store slot for new event.
Definition: SGHiveMgrSvc.cxx:98
errorcheck.h
Helpers for checking error return status codes and reporting errors.
SG::HiveMgrSvc::m_nSlots
size_t m_nSlots
Definition: SGHiveMgrSvc.h:120
SG::HiveMgrSvc::freeStore
virtual StatusCode freeStore(size_t slotIndex) override
Free a store slot.
Definition: SGHiveMgrSvc.cxx:125
SG::HiveMgrSvc::setNumProcs
static void setNumProcs(size_t numProcs)
Set number of concurrent processes.
Definition: SGHiveMgrSvc.cxx:35
DeMoScan.index
string index
Definition: DeMoScan.py:362
CloneService::clone
StatusCode clone(const IService *parent, const std::string &childName, Service *&child)
given a reference to a parent svc sets a reference to a cloned child
Definition: CloneService.cxx:21
SG::HiveMgrSvc::m_mutex
std::mutex m_mutex
Definition: SGHiveMgrSvc.h:122
python.TriggerHandler.verbose
verbose
Definition: TriggerHandler.py:296
dq_defect_virtual_defect_validation.d2
d2
Definition: dq_defect_virtual_defect_validation.py:81
SG::HiveMgrSvc::getNumberOfStores
virtual size_t getNumberOfStores() const override
Get the number of 'slots'.
Definition: SGHiveMgrSvc.cxx:86
python.SystemOfUnits.s
float s
Definition: SystemOfUnits.py:147
SG::HiveMgrSvc::setNumberOfStores
virtual StatusCode setNumberOfStores(size_t slots) override
Set the number of 'slots'.
Definition: SGHiveMgrSvc.cxx:72
s_current
__thread HiveEventSlot * s_current(0)
SGImplSvc::setSlotNumber
void setSlotNumber(int slot, int numSlots)
Set the Hive slot number for this store.
Definition: SGImplSvc.cxx:922
SG::HiveMgrSvc::clearStore
virtual StatusCode clearStore(size_t slotIndex) override
Clear a given 'slot'.
Definition: SGHiveMgrSvc.cxx:57
get_generator_info.error
error
Definition: get_generator_info.py:40
StoreGateSvc.h
dq_make_web_display.cl
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition: dq_make_web_display.py:25
python.ParticleTypeUtil.info
def info
Definition: ParticleTypeUtil.py:87
SG::HiveMgrSvc::freeSlots
virtual size_t freeSlots() override
Get free slots number.
Definition: SGHiveMgrSvc.cxx:157
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37