Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
ConcurrentBitset.h
Go to the documentation of this file.
1 // This file's extension implies that it's C, but it's really -*- C++ -*-.
2 /*
3  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
4 */
5 /*
6  */
15 #ifndef CXXUTILS_CONCURRENTBITSET_H
16 #define CXXUTILS_CONCURRENTBITSET_H
17 
18 
20 #include "CxxUtils/features.h"
21 #include "CxxUtils/ones.h"
22 #include <climits>
23 #include <vector>
24 #include <algorithm>
25 #include <iterator>
26 #include <atomic>
27 #include <mutex>
28 #include <memory>
29 #include <type_traits>
30 #include <cstddef>
31 #include <bit>
32 
33 
34 namespace CxxUtils {
35 
36 
145 {
146 private:
147  // Forward declaration of implementation class.
148  class Impl;
149 
154  typedef unsigned long Block_t;
155 
157  static const size_t BLOCKSIZE = sizeof(Block_t) * CHAR_BIT;
158 
160  static const size_t MASK = BLOCKSIZE-1;
161 
162 
163  static_assert (std::atomic<Block_t>::is_always_lock_free);
164 
165 public:
167  typedef size_t bit_t;
168 
169 
170  //========================================================================
173 
174 
179  ConcurrentBitset (bit_t nbits = 0);
180 
181 
190 
191 
203  ConcurrentBitset (std::initializer_list<bit_t> l, bit_t nbits = 0);
204 
205 
214 
215 
220 
221 
230 
231 
240 
241 
250  void emptyGarbage();
251 
252 
254  //========================================================================
257 
258 
262  bit_t capacity() const;
263 
264 
268  bit_t count() const;
269 
270 
279  bit_t size() const;
280 
281 
289  bool test (bit_t bit) const;
290 
291 
299  size_t count (bit_t bit) const;
300 
301 
305  bool empty() const;
306 
307 
311  bool none() const;
312 
313 
317  bool all() const;
318 
319 
323  bool any() const;
324 
325 
327  //========================================================================
330 
331 
339 
340 
348 
349 
357 
358 
366 
367 
376 
377 
379  //========================================================================
382 
383 
391 
392 
400 
401 
409 
410 
418 
419 
428 
429 
438 
439 
448 
449 
460 
461 
466 
467 
469  //========================================================================
472 
473 
478  bool operator== (const ConcurrentBitset& other) const;
479 
480 
485  bool operator!= (const ConcurrentBitset& other) const;
486 
487 
489  //========================================================================
492 
493 
505  ConcurrentBitset& insert (bit_t bit, bit_t new_nbits = 0);
506 
507 
528  // The enable_if is needed to keep this something like
529  // bs.insert (1, 2)
530  // from matching this overload.
531  template <class ITERATOR,
532  typename = typename std::enable_if<
533  std::is_base_of<
534  typename std::forward_iterator_tag,
535  typename std::iterator_traits<ITERATOR>::iterator_category
536  >::value> >
537  ConcurrentBitset& insert (ITERATOR beg, ITERATOR end, bit_t new_nbits = 0);
538 
539 
557  ConcurrentBitset& insert (std::initializer_list<bit_t> l, bit_t new_nbits = 0);
558 
559 
571 
572 
574  //========================================================================
577 
578 
584  class reference
585  {
586  private:
587  friend class ConcurrentBitset;
588 
589 
596 
597 
598  public:
603  reference& operator= (bool val) noexcept;
604 
605 
617  reference& operator= (const reference& r) noexcept;
618 
619 
623  operator bool() const noexcept;
624 
625 
629  bool operator~() const noexcept;
630 
631 
635  reference& flip() noexcept;
636 
637 
638  private:
640  std::atomic<Block_t>* m_block;
641 
644  };
645 
646 
651  bool operator[] (bit_t bit) const;
652 
653 
661  reference operator[] (bit_t bit);
662 
663 
665  //========================================================================
668 
669 
694  {
695  typedef std::forward_iterator_tag iterator_category;
696  typedef size_t value_type;
697  typedef ptrdiff_t difference_type;
698  typedef const value_type* pointer;
699  typedef const value_type& reference;
700 
701 
702  private:
704 
705 
715  bit_t bit,
716  const std::atomic<Block_t>* data,
717  const std::atomic<Block_t>* end);
718 
719 
720  public:
724  bit_t operator*() const;
725 
726 
731 
732 
737 
738 
743  bool operator== (const const_iterator& other) const;
744 
745 
750  bool operator!= (const const_iterator& other) const;
751 
752 
753  private:
758 
761 
763  const std::atomic<Block_t>* m_data;
764 
765 
767  const std::atomic<Block_t>* m_end;
768  };
769 
770 
775 
776 
781 
782 
788  const_iterator find (bit_t bit) const;
789 
790 
791 
793 private:
794  //========================================================================
797 
798 
803  static bit_t nBlocks (bit_t nbits);
804 
805 
813  Impl* newImpl (bit_t nbits);
814 
815 
820  void expand (bit_t new_nbits);
821 
822 
827  void expandOol (bit_t new_nbits);
828 
829 
844  class Impl
845  {
846  public:
852  void* operator new (size_t /*sz*/, bit_t nbits);
853 
854 
855  /*
856  * @brief Free an Impl structure.
857  * @param p Pointer to the object to free.
858  */
859  void operator delete (void* p);
860 
861 
866  Impl (bit_t nbits);
867 
868 
877  Impl (const Impl& other, bit_t nbits = 0);
878 
879 
880  // Assignment is unimplemented.
881  Impl& operator= (const Impl&) = delete;
882 
883 
893  void assign (const Impl& other);
894 
895 
899  bit_t nbits() const;
900 
901 
909  bool test (bit_t bit) const;
910 
911 
915  bit_t count() const;
916 
917 
921  bool none() const;
922 
923 
927  bool all() const;
928 
929 
936  std::atomic<Block_t>* block (bit_t bit);
937 
938 
945  void set (bit_t bit);
946 
947 
954  void reset (bit_t bit);
955 
956 
963  void flip (bit_t bit);
964 
965 
972  void clear();
973 
974 
981  void set();
982 
983 
990  void flip();
991 
992 
993  typedef void operator_t (std::atomic<Block_t>& a, Block_t v);
1003  void operate (operator_t op, const Impl& other);
1004 
1005 
1010  bool operator== (const Impl& other) const;
1011 
1012 
1013 
1018 
1019 
1024 
1025 
1032 
1033 
1034  private:
1036  size_t m_nbits;
1037 
1039  size_t m_nblocks;
1040 
1042  std::atomic<size_t> m_hwm;
1043 
1047  std::atomic<Block_t> m_data[1];
1048  };
1049 
1050 
1052 
1053 
1054 private:
1056  std::atomic<Impl*> m_impl;
1057 
1059  std::vector<Impl*> m_garbage;
1060 
1063  typedef std::lock_guard<mutex_t> lock_t;
1065 };
1066 
1067 
1068 } // namespace CxxUtils
1069 
1070 
1072 
1073 
1074 #endif // not CXXUTILS_CONCURRENTBITSET_H
CxxUtils::ConcurrentBitset::set
ConcurrentBitset & set(bit_t bit)
Turn on one bit.
beamspotman.r
def r
Definition: beamspotman.py:676
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
CxxUtils::ConcurrentBitset::const_iterator::value_type
size_t value_type
Definition: ConcurrentBitset.h:696
features.h
Some additional feature test macros.
CxxUtils::ConcurrentBitset::count
size_t count(bit_t bit) const
Test to see if a bit is set.
CxxUtils::ConcurrentBitset::Impl::m_nblocks
size_t m_nblocks
Number of blocks in the container.
Definition: ConcurrentBitset.h:1039
CxxUtils::ConcurrentBitset::mutex_t
std::mutex mutex_t
Mutex used for synchronization when switching to a new implementation object.
Definition: ConcurrentBitset.h:1062
CxxUtils::ConcurrentBitset::flip
ConcurrentBitset & flip(bit_t bit)
Flip the value of one bit.
CxxUtils::ConcurrentBitset::const_iterator::difference_type
ptrdiff_t difference_type
Definition: ConcurrentBitset.h:697
CxxUtils::ConcurrentBitset::const_iterator::pointer
const value_type * pointer
Definition: ConcurrentBitset.h:698
CxxUtils::ConcurrentBitset::all
bool all() const
Return true if all bits in the set are 1.
CxxUtils::ConcurrentBitset::count
bit_t count() const
Count the number of 1 bits in the set.
CxxUtils::ConcurrentBitset::Impl::clear
void clear()
Clear all bits in the set.
CxxUtils::ConcurrentBitset
Variable-sized bitset allowing (mostly) concurrent access.
Definition: ConcurrentBitset.h:145
CxxUtils::ConcurrentBitset::const_iterator::operator++
const_iterator & operator++()
Advance the iterator to the next set bit (preincrement).
CxxUtils::ConcurrentBitset::Impl::block
std::atomic< Block_t > * block(bit_t bit)
Return a pointer to the block containing bit.
BeamSpot::mutex
std::mutex mutex
Definition: InDetBeamSpotVertex.cxx:18
m_data
std::vector< T > m_data
Definition: TrackTruthMatchingBaseAlg.cxx:660
CxxUtils::ConcurrentBitset::const_iterator::operator++
const_iterator operator++(int)
Advance the iterator to the next set bit (postincrement).
CxxUtils::ConcurrentBitset::Block_t
unsigned long Block_t
Internal type used to hold the bitset data.
Definition: ConcurrentBitset.h:148
CxxUtils::ConcurrentBitset::end
const_iterator end() const
Return an end iterator.
CxxUtils::ConcurrentBitset::capacity
bit_t capacity() const
The number of bits that this container can hold.
CxxUtils::ConcurrentBitset::bit_t
size_t bit_t
A bit number.
Definition: ConcurrentBitset.h:163
CxxUtils::ConcurrentBitset::operator&=
ConcurrentBitset & operator&=(const ConcurrentBitset &other)
AND this set with another set.
CxxUtils::ConcurrentBitset::operator~
ConcurrentBitset operator~() const
Return a new set that is the complement of this set.
CxxUtils::ConcurrentBitset::operator^=
ConcurrentBitset & operator^=(const ConcurrentBitset &other)
XOR this set with another set.
CxxUtils::ConcurrentBitset::const_iterator
Iterator over all 1 bits in the set.
Definition: ConcurrentBitset.h:694
CxxUtils::ConcurrentBitset::reference::m_mask
Block_t m_mask
Mask of the referenced bit within the block.
Definition: ConcurrentBitset.h:643
athena.value
value
Definition: athena.py:124
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
CxxUtils::ConcurrentBitset::const_iterator::const_iterator
const_iterator(Block_t cache, bit_t bit, const std::atomic< Block_t > *data, const std::atomic< Block_t > *end)
Constructor.
CxxUtils::ConcurrentBitset::Impl::operate
void operate(operator_t op, const Impl &other)
Apply a binary operation.
CxxUtils::ConcurrentBitset::m_impl
std::atomic< Impl * > m_impl
The current implementation object.
Definition: ConcurrentBitset.h:1056
const
bool const RAWDATA *ch2 const
Definition: LArRodBlockPhysicsV0.cxx:560
CxxUtils::ConcurrentBitset::Impl::find
const_iterator find(bit_t bit) const
If bit bit is set, return an iterator pointing to it.
ConcurrentBitset.icc
CxxUtils::ConcurrentBitset::reset
ConcurrentBitset & reset()
Clear all bits in the set.
CxxUtils::ConcurrentBitset::const_iterator::reference
const value_type & reference
Definition: ConcurrentBitset.h:699
atomic_fetch_minmax.h
Atomic min/max functions.
CxxUtils::ConcurrentBitset::insert
ConcurrentBitset & insert(ITERATOR beg, ITERATOR end, bit_t new_nbits=0)
Set several bits to 1.
CxxUtils::ConcurrentBitset::Impl::set
void set(bit_t bit)
Turn on one bit.
CxxUtils::ConcurrentBitset::clear
ConcurrentBitset & clear()
Clear all bits in the set.
CxxUtils::ConcurrentBitset::ConcurrentBitset
ConcurrentBitset(bit_t nbits=0)
Constructor.
Definition: ConcurrentBitset.cxx:27
CxxUtils::ConcurrentBitset::Impl::Impl
Impl(const Impl &other, bit_t nbits=0)
Copy constructor.
CxxUtils::ConcurrentBitset::operator-=
ConcurrentBitset & operator-=(const ConcurrentBitset &other)
Subtract another set from this set.
CxxUtils::ConcurrentBitset::reference::reference
reference(Impl &impl, bit_t bit)
Constructor.
CxxUtils::ConcurrentBitset::const_iterator::iterator_category
std::forward_iterator_tag iterator_category
Definition: ConcurrentBitset.h:695
CxxUtils::ConcurrentBitset::operator|=
ConcurrentBitset & operator|=(const ConcurrentBitset &other)
OR this set with another set.
CxxUtils::ConcurrentBitset::reference
A reference to one bit in a set.
Definition: ConcurrentBitset.h:585
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::size
bit_t size() const
Count the number of 1 bits in the set.
CxxUtils::ConcurrentBitset::lock_t
std::lock_guard< mutex_t > lock_t
Definition: ConcurrentBitset.h:1063
CxxUtils::ConcurrentBitset::insert
ConcurrentBitset & insert(std::initializer_list< bit_t > l, bit_t new_nbits=0)
Set several bits to 1.
CxxUtils::ConcurrentBitset::Impl
Implementation object.
Definition: ConcurrentBitset.h:845
CxxUtils::ConcurrentBitset::reference::operator=
reference & operator=(bool val) noexcept
Set the referenced bit to a given value.
CxxUtils::ConcurrentBitset::reference::m_block
std::atomic< Block_t > * m_block
Pointer to the block containing the referenced bit.
Definition: ConcurrentBitset.h:640
CxxUtils::ConcurrentBitset::insert
ConcurrentBitset & insert(bit_t bit, bit_t new_nbits=0)
Set a bit to 1.
CxxUtils::ConcurrentBitset::Impl::begin
const_iterator begin() const
Return an iterator referencing the first 1 bit.
CxxUtils::ConcurrentBitset::operator!=
bool operator!=(const ConcurrentBitset &other) const
Test two sets for inequality.
CxxUtils::ConcurrentBitset::reset
ConcurrentBitset & reset(bit_t bit)
Turn off one bit.
CxxUtils
Definition: aligned_vector.h:29
CxxUtils::ConcurrentBitset::Impl::end
const_iterator end() const
Return the end iterator.
CxxUtils::ConcurrentBitset::empty
bool empty() const
Return true if there are no 1 bits in the set.
CxxUtils::ConcurrentBitset::MASK
static const size_t MASK
Mask to select out the bit offset within one Block_t.
Definition: ConcurrentBitset.h:160
ones.h
Construct a bit mask.
CxxUtils::ConcurrentBitset::Impl::m_nbits
size_t m_nbits
Number of bits in the container.
Definition: ConcurrentBitset.h:1036
CxxUtils::ConcurrentBitset::~ConcurrentBitset
~ConcurrentBitset()
Destructor.
Definition: ConcurrentBitset.cxx:95
CxxUtils::ConcurrentBitset::set
ConcurrentBitset & set(bit_t bit, bool val)
Set the value of one bit.
CxxUtils::ConcurrentBitset::find
const_iterator find(bit_t bit) const
If bit bit is set, return an iterator pointing to it.
CxxUtils::ConcurrentBitset::any
bool any() const
Return true if there are any 1 bits in the set.
CxxUtils::ConcurrentBitset::insert
ConcurrentBitset & insert(const ConcurrentBitset &other)
Turn on bits listed in another set.
CxxUtils::ConcurrentBitset::Impl::assign
void assign(const Impl &other)
Copy from another instance.
CxxUtils::ConcurrentBitset::begin
const_iterator begin() const
Return a begin iterator.
CxxUtils::ConcurrentBitset::Impl::reset
void reset(bit_t bit)
Turn off one bit.
CxxUtils::ConcurrentBitset::BLOCKSIZE
static const size_t BLOCKSIZE
Size, in bits, of Block_t.
Definition: ConcurrentBitset.h:157
CxxUtils::ConcurrentBitset::const_iterator::m_data
const std::atomic< Block_t > * m_data
Pointer to the block containing the bit which we're currently referencing.
Definition: ConcurrentBitset.h:763
CxxUtils::ConcurrentBitset::const_iterator::m_end
const std::atomic< Block_t > * m_end
Pointer to one past the last block in the set.
Definition: ConcurrentBitset.h:767
WriteBchToCool.beg
beg
Definition: WriteBchToCool.py:69
CxxUtils::ConcurrentBitset::none
bool none() const
Return true if there are no 1 bits in the set.
private
#define private
Definition: DetDescrConditionsDict_dict_fixes.cxx:13
CxxUtils::ConcurrentBitset::Impl::m_hwm
std::atomic< size_t > m_hwm
High-water mark: index of last block with a 1 bit.
Definition: ConcurrentBitset.h:1042
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::const_iterator::m_bit
bit_t m_bit
Bit number which we're currently referencing.
Definition: ConcurrentBitset.h:760
CxxUtils::ConcurrentBitset::Impl::test
bool test(bit_t bit) const
Test to see if a bit is set.
CxxUtils::ConcurrentBitset::set
ConcurrentBitset & set()
Turn on all bits in the set.
CxxUtils::ConcurrentBitset::flip
ConcurrentBitset & flip()
Flip the state of all bits in the set.
python.PyAthena.v
v
Definition: PyAthena.py:154
impl
Definition: CaloGPUClusterAndCellDataMonitorOptions.h:46
CxxUtils::ConcurrentBitset::m_mutex
mutex_t m_mutex
Definition: ConcurrentBitset.h:1064
CxxUtils::ConcurrentBitset::Impl::flip
void flip(bit_t bit)
Flip the value of one bit.
a
TList * a
Definition: liststreamerinfos.cxx:10
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
CxxUtils::ConcurrentBitset::operator=
ConcurrentBitset & operator=(const ConcurrentBitset &other)
Assignment.
Definition: ConcurrentBitset.cxx:109
CxxUtils::ConcurrentBitset::Impl::operator_t
void operator_t(std::atomic< Block_t > &a, Block_t v)
Definition: ConcurrentBitset.h:993
CxxUtils::ConcurrentBitset::newImpl
Impl * newImpl(bit_t nbits)
Create a new, uninitialized implementation object.
CxxUtils::ConcurrentBitset::const_iterator::m_cache
Block_t m_cache
Cache of the block to which we're currently pointing.
Definition: ConcurrentBitset.h:757
CxxUtils::ConcurrentBitset::emptyGarbage
void emptyGarbage()
Clean up old versions of the set.
Definition: ConcurrentBitset.cxx:149
CxxUtils::ConcurrentBitset::operator==
bool operator==(const ConcurrentBitset &other) const
Test two sets for equality.
CxxUtils::ConcurrentBitset::erase
ConcurrentBitset & erase(bit_t bit)
Turn off one bit.
CxxUtils::ConcurrentBitset::reference::flip
reference & flip() noexcept
Invert the referenced bit.
value_type
Definition: EDM_MasterSearch.h:11
xAOD::bool
setBGCode setTAP setLVL2ErrorBits bool
Definition: TrigDecision_v1.cxx:60
CxxUtils::ConcurrentBitset::nBlocks
static bit_t nBlocks(bit_t nbits)
Find number of blocks needed to hold a given number of bits.
CxxUtils::ConcurrentBitset::const_iterator::operator*
bit_t operator*() const
Return the bit number which the iterator is currently referencing.
CxxUtils::ConcurrentBitset::const_iterator::ConcurrentBitset
friend ConcurrentBitset
Definition: ConcurrentBitset.h:703
CxxUtils::ConcurrentBitset::Impl::Impl
Impl(bit_t nbits)
Constructor.
CxxUtils::ConcurrentBitset::test
bool test(bit_t bit) const
Test to see if a bit is set.