ATLAS Offline Software
Loading...
Searching...
No Matches
SGHiveMgrSvc.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "GaudiKernel/ConcurrencyFlags.h"
13
14using namespace SG;
15
17
18HiveMgrSvc::HiveMgrSvc(const std::string& name,
19 ISvcLocator* svc) : base_class(name, svc),
20 m_hiveStore(StoreID::storeName(StoreID::EVENT_STORE), name),
21 m_nSlots(1)
22{
23 declareProperty("HiveStoreSvc", m_hiveStore);
24 declareProperty("NSlots", m_nSlots, "number of event slots");
25}
26
27
36void HiveMgrSvc::setNumProcs(size_t numProcs)
37{
38 Gaudi::Concurrency::ConcurrencyFlags::setNumProcs(numProcs);
39}
40
47StatusCode HiveMgrSvc::selectStore(size_t slotIndex) {
48 s_current = &m_slots[slotIndex];
50 return StatusCode::SUCCESS;
51}
52
58StatusCode HiveMgrSvc::clearStore(size_t slotIndex) {
59 StatusCode rc(StatusCode::FAILURE);
60 if (slotIndex < m_nSlots) {
61 rc=m_slots[slotIndex].pEvtStore->clearStore();
62 if (rc.isSuccess()) {
63 SG_MSG_DEBUG ("cleared store {}", slotIndex);
64 }
65 }
66 if (!rc.isSuccess()) {
67 SG_MSG_ERROR ("could not clear store {}", slotIndex);
68 }
69 return rc;
70}
71
77StatusCode HiveMgrSvc::setNumberOfStores(size_t slots) {
78 //FIXME what if running?
79 if(FSMState() == Gaudi::StateMachine::INITIALIZED) {
80 SG_MSG_FATAL ("Too late to change the number of slots!");
81 return StatusCode::FAILURE;
82 } else {
83 m_slots.resize(slots);
84 m_nSlots = slots;
85 m_freeSlots.store(slots);
86 Gaudi::Concurrency::ConcurrencyFlags::setNumConcEvents( slots );
87 return StatusCode::SUCCESS;
88 }
89}
90
92 return m_nSlots;
93}
94
95
96
103size_t HiveMgrSvc::allocateStore( int evtNumber ) {
104 if (m_freeSlots == 0) {
105 SG_MSG_ERROR ("No slots available for event number {}", evtNumber);
106 return std::string::npos;
107 }
108 std::scoped_lock lock{m_mutex};
109 for (size_t index=0; index<m_nSlots; ++index) {
110 if( m_slots[index].eventNumber == evtNumber) {
111 SG_MSG_ERROR ("Attempt to allocate an event slot for an event that is still active: event number {}", evtNumber);
112 return std::string::npos;
113 } else if (m_slots[index].eventNumber == -1) {
114 m_slots[index].eventNumber = evtNumber;
115 SG_MSG_DEBUG ("Slot {} allocated to event number {}", index, evtNumber);
116 m_freeSlots--;
117 return index;
118 }
119 }
120 SG_MSG_ERROR ("No slots available for event number {}", evtNumber);
121 return std::string::npos;
122}
123
129StatusCode HiveMgrSvc::freeStore( size_t slotIndex ) {
130 if (slotIndex < m_nSlots) {
131 std::scoped_lock lock{m_mutex};
132 if (m_slots[slotIndex].eventNumber == -1) {
133 SG_MSG_DEBUG ("Slot {} is already free", slotIndex);
134 }
135 else {
136 m_slots[slotIndex].eventNumber = -1;
137 m_freeSlots++;
138 SG_MSG_DEBUG ("Freed slot {}", slotIndex);
139 }
140 return StatusCode::SUCCESS;
141 } else {
142 SG_MSG_ERROR ("no slot at {}", slotIndex);
143 return StatusCode::FAILURE;
144 }
145}
146
147
153size_t HiveMgrSvc::getPartitionNumber(int evtNumber) const {
154 std::scoped_lock lock{m_mutex};
155 for (size_t index=0; index<m_nSlots; ++index) {
156 if( m_slots[index].eventNumber == evtNumber) return index;
157 }
158 return std::string::npos;
159}
160
162 return m_freeSlots;
163}
164
165bool HiveMgrSvc::exists( const DataObjID& id) {
166 // this should only get called in error situations, so we
167 // don't care if it's slow
168 std::string key = id.key();
169 key.erase(0,key.find('+')+1);
170
171 if (id.clid() == 0) {
172 // this is an ugly hack in case the DataObjID gets munged
173 // upstream, and we have to re-separate it into (class,key)
174 // from "class/key"
175 std::string cl = id.fullKey();
176 cl.erase(cl.find('/'),cl.length());
177
178 DataObjID d2(std::move(cl),key);
179 return m_hiveStore->transientContains(d2.clid(), key);
180 } else {
181 return m_hiveStore->transientContains(id.clid(), key);
182 }
183
184}
185
187 SG_MSG_VERBOSE ("Initializing {}", name());
188
189 if ( !(Service::initialize().isSuccess()) ) {
190 SG_MSG_FATAL ("Unable to initialize base class");
191 return StatusCode::FAILURE;
192 }
193 //this sets the hiveStore pointer to StoreGateSvc.defaultStore
194 if (!(m_hiveStore.retrieve()).isSuccess()) {
195 SG_MSG_FATAL ("Unable to get hive event store");
196 return StatusCode::FAILURE;
197 }
198
199 //use hiveStore default impl store as prototype
200 Service* child(0);
201 SGImplSvc* pSG(0);
202
203 for( size_t i = 0; i< m_nSlots; ++i) {
204 std::ostringstream oss;
205 std::print (oss, "{}_{}", i, m_hiveStore->currentStore()->name());
206 if (CloneService::clone(m_hiveStore->currentStore(), oss.str(), child).isSuccess() &&
207 child->initialize().isSuccess() &&
208 0 != (pSG = dynamic_cast<SGImplSvc*>(child)) )
209 {
210 pSG->setSlotNumber (i, m_nSlots);
211 m_slots.push_back(SG::HiveEventSlot(pSG));
212 } else {
213 SG_MSG_FATAL ("Unable to clone event store {}", oss.str());
214 return StatusCode::FAILURE;
215 }
216 }
217
218 m_freeSlots.store( m_nSlots );
219 Gaudi::Concurrency::ConcurrencyFlags::setNumConcEvents( m_nSlots );
220
221 return selectStore(0);
222}
223
225 SG_MSG_INFO ("Finalizing {}", name());
226
227 for (SG::HiveEventSlot& s : m_slots) {
228 // The impl services are not set to active, so ServiceManager
229 // won't finalize them.
230 CHECK( s.pEvtStore->finalize() );
231 s.pEvtStore->release();
232 }
233
234 return StatusCode::SUCCESS;
235}
236
237
239{
240 // On a start transition, merge the string pool from the default store
241 // into that of each store, so that they will know about any explicit
242 // registrations that were done during initialize().
243 // See ATEAM-846.
244 for (SG::HiveEventSlot& slot : m_slots) {
245 slot.pEvtStore->mergeStringPool (*m_hiveStore->currentStore());
246 }
247 return StatusCode::SUCCESS;
248}
Helpers for checking error return status codes and reporting errors.
#define CHECK(...)
Evaluate an expression and check for errors.
static Double_t rc
__thread HiveEventSlot * s_current(0)
#define SG_MSG_DEBUG(x,...)
#define SG_MSG_VERBOSE(x,...)
#define SG_MSG_INFO(x,...)
#define SG_MSG_FATAL(x,...)
#define SG_MSG_ERROR(x,...)
The Athena Transient Store API.
Definition SGImplSvc.h:109
void setSlotNumber(int slot, int numSlots)
Set the Hive slot number for this store.
virtual StatusCode start() override
virtual size_t allocateStore(int evtnumber) override
Allocate a store slot for new event.
HiveMgrSvc(const std::string &name, ISvcLocator *svc)
Standard Service Constructor. sets active store to default event store.
virtual size_t getNumberOfStores() const override
Get the number of 'slots'.
static void setNumProcs(size_t numProcs)
Set number of concurrent processes.
virtual bool exists(const DataObjID &) override
Check if a data object exists in store.
std::atomic< size_t > m_freeSlots
virtual size_t freeSlots() override
Get free slots number.
virtual size_t getPartitionNumber(int eventnumber) const override
Get the slot number corresponding to a given event.
virtual StatusCode selectStore(size_t slotIndex) override
Activate an given 'slot' for all subsequent calls within the same thread id.
ServiceHandle< StoreGateSvc > m_hiveStore
std::mutex m_mutex
virtual StatusCode clearStore(size_t slotIndex) override
Clear a given 'slot'.
virtual StatusCode setNumberOfStores(size_t slots) override
Set the number of 'slots'.
std::vector< SG::HiveEventSlot > m_slots
virtual StatusCode initialize() override
virtual StatusCode freeStore(size_t slotIndex) override
Free a store slot.
virtual StatusCode finalize() override
static void setSlot(SG::HiveEventSlot *pSlot)
set the hive event slot pointer: used by the event loop mgrs
defines an enum used by address providers to decide what kind of StoreGateSvc they are providing addr...
Definition StoreID.h:18
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
Forward declaration.
virtual void lock() override
Lock the container.
Definition index.py:1