ATLAS Offline Software
LWPool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 
7 // //
8 // Implementation of class LWPool //
9 // //
10 // Author: Thomas H. Kittelmann (Thomas.Kittelmann@cern.ch) //
11 // Initial version: April 2009 //
12 // //
14 
15 #include "LWPool.h"
17 #include <algorithm>
18 #include <new>
19 
21 {
22  //The mother pool parameters determine the growth
23  //dynamics of all pools:
24  static constexpr unsigned extra = sizeof(LWPool)+sizeof(LWPoolAreaBookKeeper)+8;
25  static constexpr unsigned poolgrow = 16384+extra;
26  static constexpr unsigned motherpoolgrow = poolgrow*32+extra;
27  static LWPool mother ATLAS_THREAD_SAFE (poolgrow,motherpoolgrow);
28  return &mother;
29 }
30 
31 //____________________________________________________________________
32 LWPool::LWPool(unsigned chunksize)
33  : m_chunksize(chunksize),
34  m_growsize(LWPool::getMotherPool()->chunkSize())
35 {
36  //Normal constructor
37  init();
38 }
39 
40 //____________________________________________________________________
41 LWPool::LWPool(unsigned chunksize,unsigned ngrowsize)
42  : m_chunksize(chunksize),
43  m_growsize(ngrowsize)
44 {
45  //Mother pool constructor
46  init();
47 }
48 
49 //____________________________________________________________________
51 {
54  m_nchunksPerArea = UINT_MAX;
55  assert(m_chunksize>=1);
56  LWHISTMALLOC(sizeof(m_areas[0])*16);
57  m_areas.reserve(16);
58 }
59 
60 //____________________________________________________________________
62 {
63  erase();
64 }
65 
66 //____________________________________________________________________
68 {
69  std::scoped_lock lock (m_mutex);
70  for (LWPoolArea* a : m_areas) {
71  char * c = reinterpret_cast<char*>(a);
72  if (isMotherPool())
73  delete[] c;
74  else
76  }
77  m_areas.clear();
78  m_likelyNonEmptyArea = nullptr;
79  m_likelyReleaseArea = nullptr;
80 }
81 
82 //____________________________________________________________________
84 {
85  return getMotherPool()->getMemOwned();
86 }
87 
88 //____________________________________________________________________
89 long long LWPool::getMemOwned() const
90 {
91  std::scoped_lock lock (m_mutex);
92  return m_growsize*m_areas.size();
93 }
94 
95 //____________________________________________________________________
96 long long LWPool::getMemDishedOut() const {
97  std::scoped_lock lock (m_mutex);
98  long long l(0);
99  for (LWPoolArea* a : m_areas)
100  l += a->getMemDishedOut();
101  return l;
102 }
103 
104 //____________________________________________________________________
106 {
107  char * c = acquire();
108  memset(c,0,m_chunksize);
109  return c;
110 }
111 
112 //____________________________________________________________________
113 char * LWPool::searchAcquire() // Must hold lock.
114 {
116  for (LWPoolArea* a : m_areas) {
117  char * c = a->acquire();
118  if (c) {
120  return c;
121  }
122  }
123 
124  //3) All areas empty - create a new area:
126  assert(m_likelyNonEmptyArea);
127  return m_likelyNonEmptyArea->acquire();
128 }
129 
130 //____________________________________________________________________
131 LWPoolArea * LWPool::findArea(char* c) // Must hold lock
132 {
133  //Figure out which area (if any), we belong in. For reasons of cpu
134  //and (in particular) cache-efficiency we do not actually ask the
135  //classes themselves, rather we just look at their addresses (since
136  //their addresses marks the beginning of the pool-areas also):
137 
139  std::lower_bound(m_areas.begin(),m_areas.end(),reinterpret_cast<void*>(c));
140  LWPoolArea* a(areaIt==m_areas.end()?m_areas.back():*(--areaIt));
141  assert(a&&a->belongsInArea(c)&&"Trying to release chunk back to a mem-pool from which it was never acquired");
142  assert(reinterpret_cast<char*>(a)<c&&c<reinterpret_cast<char*>(a)+m_growsize);
143  return a;
144 }
145 
146 //____________________________________________________________________
147 LWPoolArea* LWPool::grow() // Must hold lock.
148 {
149  char * c(0);
150  if (isMotherPool()) {
152  c = new char[m_growsize];
153  } else {
154  c = getMotherPool()->acquire();
155  }
156  assert(c);
158 
159  if (m_nchunksPerArea==UINT_MAX)
160  m_nchunksPerArea = a->totalNumberOfChunks();
161 
162  unsigned debug(m_areas.capacity());
163  m_areas.push_back(a);
164  if (debug!=m_areas.capacity())
165  LWHISTMALLOC(sizeof(m_areas.at(0))*m_areas.capacity());
166  sort(m_areas.begin(),m_areas.end());//always keep sorted
167  //fixme: make slightly faster by manually inserting and moving up mem.
169 
170  return a;
171 }
172 
173 //____________________________________________________________________
174 void LWPool::freeArea(LWPoolArea*a) // Must hold lock
175 {
176  assert(!m_areas.empty());
177 
178  if (m_likelyNonEmptyArea==a)
180  if (m_likelyReleaseArea==a)
182 
183  //Find index of the area (fixme: use binary search!):
184  unsigned i(0);
185  const unsigned nareasplusone(m_areas.size()+1);
186  for (;i<nareasplusone;++i) {
187  if (a==m_areas.at(i))
188  break;
189  }
190  assert(i<m_areas.size());
191  const unsigned nareasminusone(nareasplusone-2);
192  if (i<nareasminusone) {
193  //This is not the last area in the list, so move those above down by one:
194  for (unsigned j=i;j<nareasminusone;++j)
195  m_areas.at(j) = m_areas.at(j+1);
196  }
197  m_areas.resize(nareasminusone);
198  char * c = reinterpret_cast<char*>(a);
199  if (isMotherPool())
200  delete[] c;
201  else
202  getMotherPool()->release(c);
203 }
204 
205 //____________________________________________________________________
207 {
208  getMotherPool()->erase();
209 }
LWPoolArea::create
static LWPoolArea * create(unsigned chunksize, char *mem, unsigned length_of_mem, unsigned nchunks=UINT_MAX)
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
LWPool::freeArea
void freeArea(LWPoolArea *)
Definition: LWPool.cxx:174
LWPoolAreaBookKeeper
Definition: LWPoolAreaBookKeeper.h:30
LWPool::searchAcquire
char * searchAcquire()
Definition: LWPool.cxx:113
LWPool::m_likelyNonEmptyArea
LWPoolArea * m_likelyNonEmptyArea
Definition: LWPool.h:44
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
LWPool::getMemDishedOut
long long getMemDishedOut() const
Definition: LWPool.cxx:96
LWPool::findArea
LWPoolArea * findArea(char *)
Definition: LWPool.cxx:131
LWPool::getMemOwned
long long getMemOwned() const
Definition: LWPool.cxx:89
LWPool::forceCleanupMotherPool
static void forceCleanupMotherPool()
Definition: LWPool.cxx:206
AthExHiveOpts.chunkSize
chunkSize
Definition: AthExHiveOpts.py:101
LWPool::m_nchunksPerArea
unsigned m_nchunksPerArea
Definition: LWPool.h:42
LWPool::acquire
char * acquire()
LWPool::grow
LWPoolArea * grow()
Definition: LWPool.cxx:147
LWPool::init
void init()
Definition: LWPool.cxx:50
lumiFormat.i
int i
Definition: lumiFormat.py:92
LWPool::m_growsize
const unsigned m_growsize
Definition: LWPool.h:41
LWPool::getMotherPool
static LWPool * getMotherPool()
Definition: LWPool.cxx:20
LWPool::acquireClean
char * acquireClean()
Definition: LWPool.cxx:105
LWPoolArea::acquire
char * acquire()
python.handimod.extra
int extra
Definition: handimod.py:522
debug
const bool debug
Definition: MakeUncertaintyPlots.cxx:53
LWPoolArea
Definition: LWPoolArea.h:25
LWPool::m_areas
std::vector< LWPoolArea * > m_areas
Definition: LWPool.h:43
LWPool::release
void release(char *)
a
TList * a
Definition: liststreamerinfos.cxx:10
LWHISTMALLOC
#define LWHISTMALLOC(s)
Definition: LWPool.h:73
LWPool::m_chunksize
const unsigned m_chunksize
Definition: LWPool.h:40
LWPool::isMotherPool
bool isMotherPool() const
Definition: LWPool.h:61
LWPool::LWPool
LWPool(unsigned chunksize)
Definition: LWPool.cxx:32
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
LWPool
Definition: LWPool.h:24
LWPool::~LWPool
~LWPool()
Definition: LWPool.cxx:61
checker_macros.h
Define macros for attributes used to control the static checker.
LWPool::m_mutex
std::mutex m_mutex
Definition: LWPool.h:46
python.compressB64.c
def c
Definition: compressB64.py:93
LWPool::erase
void erase()
Definition: LWPool.cxx:67
LWPool::m_likelyReleaseArea
LWPoolArea * m_likelyReleaseArea
Definition: LWPool.h:45
LWPool.h
LWPool::getMotherMemOwned
static long long getMotherMemOwned()
Definition: LWPool.cxx:83