Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
ConcurrentBitset.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
13 #include <bit>
14 
15 
16 namespace CxxUtils {
17 
18 
19 //*********************************************************************************
20 // Constructors, destructors, assignment.
21 
22 
28  : m_impl (new (nbits) Impl (nbits))
29 {
30 }
31 
32 
41  : m_impl (new ((*other.m_impl).nbits()) Impl ((*other.m_impl)))
42 {
43 }
44 
45 
57 ConcurrentBitset::ConcurrentBitset (std::initializer_list<bit_t> l,
58  bit_t nbits /*= 0*/)
59 {
60  if (nbits == 0) {
61  // Set the size of the set based on the maximum value in the list.
62  auto max_it = std::max_element (l.begin(), l.end());
63  if (max_it != l.end()) {
64  nbits = *max_it + 1;
65  }
66  // Round up.
67  nbits = (nbits + BLOCKSIZE-1) & ~MASK;
68  }
69  m_impl = new (nbits) Impl (nbits);
70  for (bit_t b : l) {
71  set (b);
72  }
73 }
74 
75 
84 {
85  other.emptyGarbage();
86  Impl* impl = other.m_impl;
87  other.m_impl = nullptr;
88  m_impl = impl;
89 }
90 
91 
96 {
97  delete m_impl;
98  emptyGarbage();
99 }
100 
101 
110 {
111  if (this != &other) {
112  const Impl* otherImpl = other.m_impl;
113  expand (otherImpl->nbits());
114  (*m_impl).assign (*otherImpl);
115  }
116  return *this;
117 }
118 
119 
128 {
129  if (this != &other) {
130  emptyGarbage();
131  other.emptyGarbage();
132  delete m_impl;
133  Impl* impl = other.m_impl;
134  other.m_impl = nullptr;
135  m_impl = impl;
136  }
137  return *this;
138 }
139 
140 
150 {
151  lock_t lock (m_mutex);
152  for (Impl* p : m_garbage) {
153  free (p);
154  }
155  m_garbage.clear();
156 }
157 
158 
164 {
165  // Need to take out the lock.
166  lock_t lock (m_mutex);
167  // Check the size again while we're holding the lock.
168  bit_t nbits = (*m_impl).nbits();
169  if (new_nbits > nbits) {
170  // We need to expand. Allocate a new implementation and initialize it,
171  // copying from the existing implementation.
172  Impl* i = new (new_nbits) Impl (*m_impl, new_nbits);
173 
174  // Remember that we need to delete the old object.
175  m_garbage.push_back (m_impl);
176 
177  // Publish the new one.
178  m_impl = i;
179  }
180 }
181 
182 
183 //*********************************************************************************
184 // Implementation.
185 
186 
192 {
193  bit_t n = 0;
194  for (bit_t i=0; i<m_nblocks; i++) {
195  n += std::popcount (m_data[i].load());
196  }
197  return n;
198 }
199 
200 
205 {
206  for (bit_t i = 0; i < m_nblocks; i++) {
207  if (m_data[i]) return false;
208  }
209  return true;
210 }
211 
212 
217 {
218  if (m_nblocks == 0) {
219  return true;
220  }
221 
222  // Check all blocks except the last.
223  for (bit_t i = 0; i < m_nblocks-1; i++) {
224  if (m_data[i] != ~static_cast<Block_t>(0)) return false;
225  }
226  // Special case for the last, since the last block may not be full.
227  if (m_data[m_nblocks] != ones<Block_t> (m_nbits - (m_nblocks-1)*BLOCKSIZE)) {
228  return false;
229  }
230  return true;
231 }
232 
233 
241 {
242  for (bit_t i=0; i<m_nblocks; i++) {
243  m_data[i].store (~static_cast<Block_t>(0), std::memory_order_relaxed);
244  }
245  std::atomic_thread_fence (std::memory_order_seq_cst);
246  if (m_nblocks > 0) {
247  m_hwm = m_nblocks-1;
248  }
249 }
250 
251 
259 {
260  for (bit_t i=0; i<m_nblocks; i++) {
261  m_data[i] ^= ~static_cast<Block_t>(0);
262  }
263  if (m_nblocks > 0) {
264  m_hwm = m_nblocks-1;
265  }
266 }
267 
268 
269 } // namespace CxxUtils
CxxUtils::ConcurrentBitset::Impl::m_nblocks
size_t m_nblocks
Number of blocks in the container.
Definition: ConcurrentBitset.h:1039
ConcurrentBitset.h
Variable-sized bitset allowing (mostly) concurrent access.
CxxUtils::ConcurrentBitset::Impl::count
bit_t count() const
Count the number of 1 bits in the set.
Definition: ConcurrentBitset.cxx:191
CxxUtils::ConcurrentBitset
Variable-sized bitset allowing (mostly) concurrent access.
Definition: ConcurrentBitset.h:145
m_data
std::vector< T > m_data
Definition: TrackTruthMatchingBaseAlg.cxx:660
CxxUtils::ConcurrentBitset::Block_t
unsigned long Block_t
Internal type used to hold the bitset data.
Definition: ConcurrentBitset.h:148
CSV_InDetExporter.new
new
Definition: CSV_InDetExporter.py:145
CxxUtils::ConcurrentBitset::bit_t
size_t bit_t
A bit number.
Definition: ConcurrentBitset.h:163
CxxUtils::ConcurrentBitset::Impl::all
bool all() const
Return true if all bits in the set are 1.
Definition: ConcurrentBitset.cxx:216
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
CxxUtils::ConcurrentBitset::Impl::flip
void flip()
Flip the state of all bits in the set.
Definition: ConcurrentBitset.cxx:258
CxxUtils::ConcurrentBitset::m_impl
std::atomic< Impl * > m_impl
The current implementation object.
Definition: ConcurrentBitset.h:1056
CxxUtils::ConcurrentBitset::ConcurrentBitset
ConcurrentBitset(bit_t nbits=0)
Constructor.
Definition: ConcurrentBitset.cxx:27
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
CxxUtils::ConcurrentBitset::expandOol
void expandOol(bit_t new_nbits)
Expand the container: out-of-line portion.
Definition: ConcurrentBitset.cxx:163
CxxUtils::ConcurrentBitset::lock_t
std::lock_guard< mutex_t > lock_t
Definition: ConcurrentBitset.h:1063
CxxUtils::ConcurrentBitset::Impl::none
bool none() const
Return true if there are no 1 bits in the set.
Definition: ConcurrentBitset.cxx:204
CxxUtils::ConcurrentBitset::Impl
Implementation object.
Definition: ConcurrentBitset.h:845
CxxUtils::ConcurrentBitset::Impl::set
void set()
Turn on all bits in the set.
Definition: ConcurrentBitset.cxx:240
lumiFormat.i
int i
Definition: lumiFormat.py:85
CxxUtils::ConcurrentBitset::Impl::m_data
std::atomic< Block_t > m_data[1]
The set data.
Definition: ConcurrentBitset.h:1047
beamspotman.n
n
Definition: beamspotman.py:731
CxxUtils
Definition: aligned_vector.h:29
CxxUtils::ConcurrentBitset::MASK
static const size_t MASK
Mask to select out the bit offset within one Block_t.
Definition: ConcurrentBitset.h:160
CxxUtils::ConcurrentBitset::~ConcurrentBitset
~ConcurrentBitset()
Destructor.
Definition: ConcurrentBitset.cxx:95
CxxUtils::ConcurrentBitset::BLOCKSIZE
static const size_t BLOCKSIZE
Size, in bits, of Block_t.
Definition: ConcurrentBitset.h:157
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
CxxUtils::ConcurrentBitset::expand
void expand(bit_t new_nbits)
Expand the container.
CxxUtils::ConcurrentBitset::Impl::nbits
bit_t nbits() const
Return the number of bits in the set.
CxxUtils::ConcurrentBitset::m_garbage
std::vector< Impl * > m_garbage
Old implementation objects, pending deletion.
Definition: ConcurrentBitset.h:1059
CxxUtils::ConcurrentBitset::set
ConcurrentBitset & set()
Turn on all bits in the set.
impl
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:46
CxxUtils::ConcurrentBitset::m_mutex
mutex_t m_mutex
Definition: ConcurrentBitset.h:1064
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
CxxUtils::ConcurrentBitset::operator=
ConcurrentBitset & operator=(const ConcurrentBitset &other)
Assignment.
Definition: ConcurrentBitset.cxx:109
python.root_pickle.load
def load(f, use_proxy=1, key=None)
Definition: root_pickle.py:476
CxxUtils::ConcurrentBitset::emptyGarbage
void emptyGarbage()
Clean up old versions of the set.
Definition: ConcurrentBitset.cxx:149