Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Classes | Public Types | Public Member Functions | Static Public Attributes | Protected Member Functions | Private Types | Private Attributes | Friends | List of all members
EventContainers::IdentifiableCacheBase Class Reference

#include <IdentifiableCacheBase.h>

Inheritance diagram for EventContainers::IdentifiableCacheBase:
Collaboration diagram for EventContainers::IdentifiableCacheBase:

Classes

struct  IMaker
 

Public Types

typedef std::true_type thread_safe
 

Public Member Functions

const void * find (IdentifierHash hash) noexcept
 Return payload if there, null if not there. More...
 
const void * findWait (IdentifierHash hash)
 Retrieve ptr, will wait if there is something in progress. More...
 
const void * get (IdentifierHash hash)
 Try to make payload if not there. More...
 
std::vector< IdentifierHashids ()
 In a threaded situation this collection will be valid but will not container hashes later added. More...
 
std::pair< bool, const void * > add (IdentifierHash hash, const void *p) noexcept
 
std::pair< bool, const void * > addLock (IdentifierHash hash, const void *p) noexcept
 
std::pair< bool, const void * > addLock (IdentifierHash hash, void_unique_ptr p) noexcept
 
std::pair< bool, const void * > add (IdentifierHash hash, void_unique_ptr p) noexcept
 
bool IMakerPresent () const
 
int tryLock (IdentifierHash, IDC_WriteHandleBase &, std::vector< IdentifierHash > &)
 Checks if the item is completed if it is not started it extablishes lock (returns 0), If it is started but not completed it adds to wait list (returns 1) If the item is already completed it returns 2 If the item is aborted it does nothing and returns 3. More...
 
int itemAborted (IdentifierHash)
 Returns 1 is the item has been aborted otherwise 0. More...
 
int itemInProgress (IdentifierHash)
 Returns 1 is the item is inprogress otherwise 0. More...
 
const void * waitFor (IdentifierHash)
 Halts the thread until the require hash is completed or aborted. More...
 
void createSet (const std::vector< IdentifierHash > &hashes, std::vector< bool > &mask)
 Create a set of hashes, updates an IDC mask as appropriate. More...
 
size_t fullSize () const
 
size_t numberOfHashes ()
 In a concurrent situation this number isn't necessarily perfectly synchronised with ids().size() More...
 

Static Public Attributes

static constexpr uintptr_t INVALIDflag = UINTPTR_MAX
 
static constexpr uintptr_t ABORTEDflag = UINTPTR_MAX-1
 

Protected Member Functions

 IdentifiableCacheBase (IdentifierHash maxHash, const IMaker *maker)
 
 ~IdentifiableCacheBase ()
 
void clear (deleter_f *deleter)
 
void cleanUp (deleter_f *deleter)
 
void notifyHash (IdentifierHash hash)
 

Private Types

typedef std::mutex mutex_t
 
typedef std::scoped_lock< mutex_tlock_t
 
typedef std::unique_lock< mutex_tuniqueLock
 

Private Attributes

std::vector< std::atomic< const void * > > m_vec
 
const IMakerm_maker
 
mutex_t m_mutex
 
std::atomic< size_t > m_currentHashes
 Holds the number of valid hashes in container, in concurrent use it is not guaranteed to be up to date. More...
 

Friends

class InternalOnline
 

Detailed Description

Definition at line 25 of file IdentifiableCacheBase.h.

Member Typedef Documentation

◆ lock_t

typedef std::scoped_lock<mutex_t> EventContainers::IdentifiableCacheBase::lock_t
private

Definition at line 100 of file IdentifiableCacheBase.h.

◆ mutex_t

Definition at line 99 of file IdentifiableCacheBase.h.

◆ thread_safe

Definition at line 34 of file IdentifiableCacheBase.h.

◆ uniqueLock

Definition at line 101 of file IdentifiableCacheBase.h.

Constructor & Destructor Documentation

◆ IdentifiableCacheBase()

EventContainers::IdentifiableCacheBase::IdentifiableCacheBase ( IdentifierHash  maxHash,
const IMaker maker 
)
protected

Definition at line 28 of file IdentifiableCacheBase.cxx.

30  : m_vec(maxHash),
31  m_maker (maker),
33 {
34 }

◆ ~IdentifiableCacheBase()

EventContainers::IdentifiableCacheBase::~IdentifiableCacheBase ( )
protecteddefault

Member Function Documentation

◆ add() [1/2]

std::pair< bool, const void * > EventContainers::IdentifiableCacheBase::add ( IdentifierHash  hash,
const void *  p 
)
noexcept

Definition at line 204 of file IdentifiableCacheBase.cxx.

205 {
206  if (ATH_UNLIKELY(hash >= m_vec.size())) return std::make_pair(false, nullptr);
207  if(p==nullptr) return std::make_pair(false, nullptr);
208  const void* nul=nullptr;
209  if(m_vec[hash].compare_exchange_strong(nul, p, std::memory_order_release, std::memory_order_relaxed)){
210  m_currentHashes.fetch_add(1, std::memory_order_relaxed);
211  return std::make_pair(true, p);
212  }
213  const void* invalid = INVALID;
214  if(m_vec[hash].compare_exchange_strong(invalid, p, std::memory_order_release, std::memory_order_acquire)){
215  m_currentHashes.fetch_add(1, std::memory_order_relaxed);
216  notifyHash(hash);
217  return std::make_pair(true, p);
218  }
219  return std::make_pair(false, invalid);
220 }

◆ add() [2/2]

std::pair< bool, const void * > EventContainers::IdentifiableCacheBase::add ( IdentifierHash  hash,
void_unique_ptr  p 
)
noexcept

Definition at line 251 of file IdentifiableCacheBase.cxx.

253 {
254  std::pair<bool, const void*> b = add(hash, p.get());
255  if(b.first) p.release();
256  return b;
257 }

◆ addLock() [1/2]

std::pair< bool, const void * > EventContainers::IdentifiableCacheBase::addLock ( IdentifierHash  hash,
const void *  p 
)
noexcept

Definition at line 223 of file IdentifiableCacheBase.cxx.

224 { //Same as method above except we check for invalid state first,
225  // more optimal for calling using writehandle lock method
226  assert(hash < m_vec.size());
227  if(p==nullptr) return std::make_pair(false, nullptr);
228  const void* invalid = INVALID;
229  if(m_vec[hash].compare_exchange_strong(invalid, p, std::memory_order_release, std::memory_order_relaxed)){
230  m_currentHashes.fetch_add(1, std::memory_order_relaxed);
231  notifyHash(hash);
232  return std::make_pair(true, p);
233  }
234  const void* nul=nullptr;
235  if(m_vec[hash].compare_exchange_strong(nul, p, std::memory_order_release, std::memory_order_acquire)){
236  m_currentHashes.fetch_add(1, std::memory_order_relaxed);
237  return std::make_pair(true, p);
238  }
239  return std::make_pair(false, nul);
240 }

◆ addLock() [2/2]

std::pair< bool, const void * > EventContainers::IdentifiableCacheBase::addLock ( IdentifierHash  hash,
void_unique_ptr  p 
)
noexcept

Definition at line 242 of file IdentifiableCacheBase.cxx.

244 {
245  std::pair<bool, const void*> b = addLock(hash, p.get());
246  if(b.first) p.release();
247  return b;
248 }

◆ cleanUp()

void EventContainers::IdentifiableCacheBase::cleanUp ( deleter_f deleter)
protected

Definition at line 78 of file IdentifiableCacheBase.cxx.

79 {
80  std::atomic_thread_fence(std::memory_order_acquire);
81  if(0 != m_currentHashes.load(std::memory_order_relaxed)){ //Reduce overhead if cache was unused
82  size_t s = m_vec.size();
83  for (size_t i=0; i<s ;i++) {
84  const void* p = m_vec[i].load(std::memory_order_relaxed);
85  if(p && p < ABORTED) deleter (p);
86  }
87  }
88 }

◆ clear()

void EventContainers::IdentifiableCacheBase::clear ( deleter_f deleter)
protected

Definition at line 59 of file IdentifiableCacheBase.cxx.

60 {
61  size_t s = m_vec.size();
62  if(0 != m_currentHashes.load(std::memory_order_relaxed)){
63  for (size_t i=0; i<s ;i++) {
64  const void* ptr = m_vec[i].load(std::memory_order_relaxed);
65  m_vec[i].store(nullptr, std::memory_order_relaxed);
66  if (ptr && ptr < ABORTED){
67  deleter (ptr);
68  }
69  }
70  m_currentHashes.store(0, std::memory_order_relaxed);
71  }else{
72  for (size_t i=0; i<s ;i++) m_vec[i].store(nullptr, std::memory_order_relaxed);//Need to clear incase of aborts
73  }
74 }

◆ createSet()

void EventContainers::IdentifiableCacheBase::createSet ( const std::vector< IdentifierHash > &  hashes,
std::vector< bool > &  mask 
)

Create a set of hashes, updates an IDC mask as appropriate.

Definition at line 176 of file IdentifiableCacheBase.cxx.

176  {
177  assert(mask.size() == fullSize());
178  for(IdentifierHash hash : hashes){
179  const void* ptr = get(hash);
180  if(ptr !=nullptr) mask[hash] = true;
181  }
182 }

◆ find()

const void * EventContainers::IdentifiableCacheBase::find ( IdentifierHash  hash)
noexcept

Return payload if there, null if not there.

Definition at line 102 of file IdentifiableCacheBase.cxx.

103 {
104  if (ATH_UNLIKELY(hash >= m_vec.size())) return nullptr;
105  const void* p = m_vec[hash].load(std::memory_order_acquire);
106  if (p >= ABORTED)
107  return nullptr;
108  return p;
109 }

◆ findWait()

const void * EventContainers::IdentifiableCacheBase::findWait ( IdentifierHash  hash)

Retrieve ptr, will wait if there is something in progress.

Definition at line 123 of file IdentifiableCacheBase.cxx.

124 {
125  if (ATH_UNLIKELY(hash >= m_vec.size())) return nullptr;
126  const void* p = waitFor(hash);
127  if(p>=ABORTED) return nullptr;
128  return p;
129 }

◆ fullSize()

size_t EventContainers::IdentifiableCacheBase::fullSize ( ) const
inline

Definition at line 84 of file IdentifiableCacheBase.h.

84 { return m_vec.size(); }

◆ get()

const void * EventContainers::IdentifiableCacheBase::get ( IdentifierHash  hash)

Try to make payload if not there.

Definition at line 136 of file IdentifiableCacheBase.cxx.

137 {
138  // If it's there already, return directly without locking.
139  const void* ptr = nullptr;
140  if (ATH_UNLIKELY(hash >= m_vec.size())) return ptr;
141 
142  if(m_vec[hash].compare_exchange_strong(ptr, INVALID) ) {//Exchanges ptr with current value!!
143  // Make the payload.
144  if(m_maker == nullptr){
145  m_vec[hash].store( ABORTED );
146  return nullptr;
147  }
148  uniqueLock lock(m_mutex, std::defer_lock);
149  if(!m_maker->m_IsReEntrant) lock.lock();//Allow reentrant or non reentrant makers
150 
151  try {
152  ptr = m_maker->typelessMake (hash).release();
153  }
154  catch (...) {
155  // FIXME: Can this be done with RAII?
156  notifyHash(hash);
157  throw;
158  }
159  assert(m_vec[hash] == INVALID);
160  if(ptr){
161  m_vec[hash].store( ptr );
162  m_currentHashes++;
163  }else{
164  m_vec[hash].store( ABORTED );
165  }
166  notifyHash(hash);
167  }
168  else if(ptr == INVALID){
169  ptr= waitFor(hash);
170  }
171  if(ptr == ABORTED) return nullptr;
172  assert(ptr < ABORTED);
173  return ptr;
174 }

◆ ids()

std::vector< IdentifierHash > EventContainers::IdentifiableCacheBase::ids ( )

In a threaded situation this collection will be valid but will not container hashes later added.

Definition at line 190 of file IdentifiableCacheBase.cxx.

191 {
192  std::vector<IdentifierHash> ret;
193  ret.reserve (m_currentHashes.load(std::memory_order_relaxed));
194  size_t s = m_vec.size();
195  for (size_t i =0; i<s; i++) {
196  const void* p = m_vec[i].load(std::memory_order_relaxed);
197  if (p && p < ABORTED)
198  ret.push_back (i);
199  }
200  return ret;
201 }

◆ IMakerPresent()

bool EventContainers::IdentifiableCacheBase::IMakerPresent ( ) const
inline

Definition at line 64 of file IdentifiableCacheBase.h.

64 { return m_maker!=nullptr; }

◆ itemAborted()

int EventContainers::IdentifiableCacheBase::itemAborted ( IdentifierHash  hash)

Returns 1 is the item has been aborted otherwise 0.

Definition at line 90 of file IdentifiableCacheBase.cxx.

90  {
91  const void* p = m_vec[hash].load(std::memory_order_relaxed); //Relaxed because it is not returning a pointer to anything
92  return (p == ABORTED);
93 }

◆ itemInProgress()

int EventContainers::IdentifiableCacheBase::itemInProgress ( IdentifierHash  hash)

Returns 1 is the item is inprogress otherwise 0.

Definition at line 96 of file IdentifiableCacheBase.cxx.

96  {
97  const void* p = m_vec[hash].load(std::memory_order_relaxed); //Relaxed because it is not returning a pointer to anything
98  return (p == INVALID);
99 }

◆ notifyHash()

void EventContainers::IdentifiableCacheBase::notifyHash ( IdentifierHash  hash)
protected

Definition at line 131 of file IdentifiableCacheBase.cxx.

132 {
133  m_vec[hash].notify_all();
134 }

◆ numberOfHashes()

size_t EventContainers::IdentifiableCacheBase::numberOfHashes ( )

In a concurrent situation this number isn't necessarily perfectly synchronised with ids().size()

Definition at line 185 of file IdentifiableCacheBase.cxx.

186 {
187  return m_currentHashes.load(std::memory_order_relaxed); //Not to be used for syncing
188 }

◆ tryLock()

int EventContainers::IdentifiableCacheBase::tryLock ( IdentifierHash  hash,
IDC_WriteHandleBase lock,
std::vector< IdentifierHash > &  wait 
)

Checks if the item is completed if it is not started it extablishes lock (returns 0), If it is started but not completed it adds to wait list (returns 1) If the item is already completed it returns 2 If the item is aborted it does nothing and returns 3.

Definition at line 39 of file IdentifiableCacheBase.cxx.

39  {
40  const void *ptr1 =nullptr;
41 
42  if(m_vec[hash].compare_exchange_strong(ptr1, INVALID, std::memory_order_relaxed, std::memory_order_relaxed)){//atomic swap (replaces ptr1 with value)
43  //First call
44  //Setup the IDC_WriteHandle to "lock" on this hash's pointer
45  lock.LockOn(&m_vec[hash]);
46  return 0;
47  }
48 
49  if(ptr1 == INVALID){
50  //Second call while not finished
51  wait.emplace_back(hash);
52  return 1;
53  }
54  if(ptr1 == ABORTED) return 3;
55  return 2; //Already completed
56 }

◆ waitFor()

const void * EventContainers::IdentifiableCacheBase::waitFor ( IdentifierHash  hash)

Halts the thread until the require hash is completed or aborted.

Definition at line 111 of file IdentifiableCacheBase.cxx.

112 {
113  std::atomic<const void*> &myatomic = m_vec[hash];
114  const void* item = myatomic.load(std::memory_order_acquire);
115  //Wait until pointer is set then retrieve and verify
116  while(item == INVALID){//Loop to check for spurious wakeups
117  myatomic.wait(item, std::memory_order_relaxed);
118  item = myatomic.load(std::memory_order_acquire);
119  }
120  return item;
121 }

Friends And Related Function Documentation

◆ InternalOnline

friend class InternalOnline
friend

Definition at line 96 of file IdentifiableCacheBase.h.

Member Data Documentation

◆ ABORTEDflag

constexpr uintptr_t EventContainers::IdentifiableCacheBase::ABORTEDflag = UINTPTR_MAX-1
staticconstexpr

Definition at line 31 of file IdentifiableCacheBase.h.

◆ INVALIDflag

constexpr uintptr_t EventContainers::IdentifiableCacheBase::INVALIDflag = UINTPTR_MAX
staticconstexpr

Definition at line 30 of file IdentifiableCacheBase.h.

◆ m_currentHashes

std::atomic<size_t> EventContainers::IdentifiableCacheBase::m_currentHashes
private

Holds the number of valid hashes in container, in concurrent use it is not guaranteed to be up to date.

Definition at line 104 of file IdentifiableCacheBase.h.

◆ m_maker

const IMaker* EventContainers::IdentifiableCacheBase::m_maker
private

Definition at line 97 of file IdentifiableCacheBase.h.

◆ m_mutex

mutex_t EventContainers::IdentifiableCacheBase::m_mutex
private

Definition at line 102 of file IdentifiableCacheBase.h.

◆ m_vec

std::vector<std::atomic<const void*> > EventContainers::IdentifiableCacheBase::m_vec
private

Definition at line 95 of file IdentifiableCacheBase.h.


The documentation for this class was generated from the following files:
EventContainers::ABORTED
const void *const ABORTED
Definition: IdentifiableCacheBase.cxx:24
python.root_lsr_rank.hashes
hashes
Definition: root_lsr_rank.py:34
SGTest::store
TestStore store
Definition: TestStore.cxx:23
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
EventContainers::IdentifiableCacheBase::get
const void * get(IdentifierHash hash)
Try to make payload if not there.
Definition: IdentifiableCacheBase.cxx:136
EventContainers::INVALID
const void *const INVALID
Definition: IdentifiableCacheBase.cxx:23
EventContainers::IdentifiableCacheBase::IMaker::m_IsReEntrant
bool m_IsReEntrant
Definition: IdentifiableCacheBase.h:40
EventContainers::IdentifiableCacheBase::m_mutex
mutex_t m_mutex
Definition: IdentifiableCacheBase.h:102
EventContainers::IdentifiableCacheBase::m_maker
const IMaker * m_maker
Definition: IdentifiableCacheBase.h:97
ATH_UNLIKELY
#define ATH_UNLIKELY(x)
Definition: AthUnlikelyMacros.h:17
dbg::ptr
void * ptr(T *p)
Definition: SGImplSvc.cxx:74
python.utils.AtlRunQueryLookup.mask
string mask
Definition: AtlRunQueryLookup.py:460
PyPoolBrowser.item
item
Definition: PyPoolBrowser.py:129
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
lumiFormat.i
int i
Definition: lumiFormat.py:85
EventContainers::IdentifiableCacheBase::fullSize
size_t fullSize() const
Definition: IdentifiableCacheBase.h:84
EventContainers::IdentifiableCacheBase::uniqueLock
std::unique_lock< mutex_t > uniqueLock
Definition: IdentifiableCacheBase.h:101
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
EventContainers::IdentifiableCacheBase::notifyHash
void notifyHash(IdentifierHash hash)
Definition: IdentifiableCacheBase.cxx:131
EventContainers::IdentifiableCacheBase::m_currentHashes
std::atomic< size_t > m_currentHashes
Holds the number of valid hashes in container, in concurrent use it is not guaranteed to be up to dat...
Definition: IdentifiableCacheBase.h:104
item
Definition: ItemListSvc.h:43
EventContainers::IdentifiableCacheBase::m_vec
std::vector< std::atomic< const void * > > m_vec
Definition: IdentifiableCacheBase.h:95
EventContainers::IdentifiableCacheBase::IMaker::typelessMake
virtual void_unique_ptr typelessMake(IdentifierHash hash) const =0
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:109
EventContainers::IdentifiableCacheBase::waitFor
const void * waitFor(IdentifierHash)
Halts the thread until the require hash is completed or aborted.
Definition: IdentifiableCacheBase.cxx:111
EventContainers::IdentifiableCacheBase::add
std::pair< bool, const void * > add(IdentifierHash hash, const void *p) noexcept
Definition: IdentifiableCacheBase.cxx:204
IdentifierHash
This is a "hash" representation of an Identifier. This encodes a 32 bit index which can be used to lo...
Definition: IdentifierHash.h:25
EventContainers::IdentifiableCacheBase::addLock
std::pair< bool, const void * > addLock(IdentifierHash hash, const void *p) noexcept
Definition: IdentifiableCacheBase.cxx:223