ATLAS Offline Software
RCUObject.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
12 #include "AthenaKernel/RCUObject.h"
13 #include "AthenaKernel/IRCUSvc.h"
14 #include "boost/dynamic_bitset.hpp"
15 #include <cstdlib>
16 
17 
18 namespace {
19 
20 
31 inline
32 bool endGrace (const EventContext& ctx,
33  boost::dynamic_bitset<>& grace)
34 {
35  EventContext::ContextID_t slot = ctx.slot();
36  if (slot == EventContext::INVALID_CONTEXT_ID) return false;
37  if (slot >= grace.size()) std::abort();
38  grace[slot] = false;
39  return grace.any();
40 }
41 
42 
43 } // anonymous namespace
44 
45 
46 namespace Athena {
47 
48 
50 {
51  RCUObjectGraceSets (size_t nslots)
52  : m_grace (nslots),
53  m_oldGrace (nslots)
54  {
55  }
56 
57 
59  boost::dynamic_bitset<> m_grace;
60 
62  boost::dynamic_bitset<> m_oldGrace;
63 };
64 
65 
73  : m_svc (&svc),
74  m_graceSets (std::make_unique<RCUObjectGraceSets> (svc.getNumSlots())),
75  m_nold(0),
76  m_dirty(false)
77 {
78  m_svc->add (this);
79 }
80 
81 
88 IRCUObject::IRCUObject (size_t nslots)
89  : m_svc (nullptr),
90  m_graceSets (std::make_unique<RCUObjectGraceSets> (nslots)),
91  m_nold(0),
92  m_dirty(false)
93 {
94 }
95 
96 
103 {
104  if (m_svc && m_svc->remove (this).isFailure())
105  std::abort();
106 }
107 
108 
115  : m_svc (other.m_svc),
116  m_graceSets (std::move (other.m_graceSets)),
117  m_nold (other.m_nold),
118  m_dirty (false)
119 {
120  other.m_nold = 0;
121  if (other.m_dirty) {
122  m_dirty = true;
123  }
124  other.m_dirty = false;
125  if (m_svc) {
126  if (m_svc->remove (&other).isFailure()) {
127  std::abort();
128  }
129  other.m_svc = nullptr;
130  m_svc->add (this);
131  }
132 }
133 
134 
138 void IRCUObject::quiescentOol (const EventContext& ctx)
139 {
140  // We get here after the dirty flag has already been checked.
141  lock_t g (m_mutex);
142  if (!::endGrace(ctx, m_graceSets->m_grace)) {
143  clearAll(g);
144  m_nold = 0;
145  m_dirty = false;
146  }
147  else if (m_nold > 0 && !::endGrace(ctx, m_graceSets->m_oldGrace)) {
148  if (clearOld(g, m_nold)) {
149  m_dirty = false;
150  }
151  m_nold = 0;
152  }
153 }
154 
155 
165 bool IRCUObject::endGrace (lock_t& /*lock*/, const EventContext& ctx)
166 {
167  return ::endGrace (ctx, m_graceSets->m_grace);
168 }
169 
170 
177 void IRCUObject::setGrace (lock_t& /*lock*/)
178 {
179  m_graceSets->m_grace.set();
180  if (!m_dirty) m_dirty = true;
181 }
182 
183 
193 void IRCUObject::makeOld (lock_t& /*lock*/, size_t garbageSize)
194 {
195  if (garbageSize && m_nold == 0) {
196  m_graceSets->m_oldGrace = m_graceSets->m_grace;
197  m_nold = garbageSize;
198  }
199 }
200 
201 
202 } // namespace Athena
Athena::IRCUObject::quiescentOol
void quiescentOol(const EventContext &ctx)
Out-of-line part of quiescent().
Definition: RCUObject.cxx:138
Athena::RCUObjectGraceSets::m_oldGrace
boost::dynamic_bitset m_oldGrace
Same thing, for the objects marked as old.
Definition: RCUObject.cxx:62
Athena::IRCUObject::m_dirty
std::atomic< bool > m_dirty
True if there are any objects pending deletion.
Definition: RCUObject.h:300
RCUObject.h
read-copy-update (RCU) style synchronization for Athena.
Athena::IRCUObject::IRCUObject
IRCUObject(IRCUSvc &svc)
Constructor, with RCUSvc.
Definition: RCUObject.cxx:72
Athena::IRCUObject::m_svc
IRCUSvc * m_svc
The service with which we're registered, or null.
Definition: RCUObject.h:288
Athena::IRCUObject::clearOld
virtual bool clearOld(lock_t &, size_t nold)=0
Delete old objects.
Athena::RCUObjectGraceSets
Definition: RCUObject.cxx:50
Athena::IRCUSvc::add
virtual void add(IRCUObject *obj)=0
Add a new RCU object to the set being managed.
Athena::IRCUObject::~IRCUObject
virtual ~IRCUObject()
Destructor.
Definition: RCUObject.cxx:102
Athena::RCUObjectGraceSets::RCUObjectGraceSets
RCUObjectGraceSets(size_t nslots)
Definition: RCUObject.cxx:51
Athena::IRCUObject::m_nold
size_t m_nold
Number of old objects.
Definition: RCUObject.h:296
Athena::RCUObjectGraceSets::m_grace
boost::dynamic_bitset m_grace
Bit[i] set means that slot i is in a grace period.
Definition: RCUObject.cxx:59
IRCUSvc.h
read-copy-update (RCU) style synchronization for Athena.
Athena
Some weak symbol referencing magic...
Definition: AthLegacySequence.h:21
python.CaloCondTools.g
g
Definition: CaloCondTools.py:15
Athena::IRCUObject::makeOld
void makeOld(lock_t &lock, size_t garbageSize)
Make existing pending objects old, if possible.
Definition: RCUObject.cxx:193
Athena::IRCUSvc
Interface for RCU service.
Definition: IRCUSvc.h:40
Athena::IRCUObject::m_mutex
std::mutex m_mutex
The mutex for this object.
Definition: RCUObject.h:285
Athena::IRCUObject::lock_t
std::unique_lock< mutex_t > lock_t
Definition: RCUObject.h:214
Handler::svc
AthROOTErrorHandlerSvc * svc
Definition: AthROOTErrorHandlerSvc.cxx:10
Athena::IRCUSvc::remove
virtual StatusCode remove(IRCUObject *obj)=0
Remove an object from the service.
Athena::IRCUObject::setGrace
void setGrace(lock_t &)
Declare that all slots are in a grace period.
Definition: RCUObject.cxx:177
Athena::IRCUObject
Base object class for RCU-style synchronization for Athena.
Definition: RCUObject.h:147
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
Athena::IRCUObject::clearAll
virtual void clearAll(lock_t &)=0
Delete all objects.
Athena::IRCUObject::endGrace
bool endGrace(lock_t &lock, const EventContext &ctx)
Declare that the grace period for a slot is ending.
Definition: RCUObject.cxx:165
Athena::IRCUObject::m_graceSets
std::unique_ptr< RCUObjectGraceSets > m_graceSets
Holds the current and old grace period bitmasks.
Definition: RCUObject.h:292