ATLAS Offline Software
ArenaBlock.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
16 #include <cstdlib>
17 #include <unistd.h>
18 #include <cassert>
19 #include <sys/mman.h>
20 
21 
22 namespace SG {
23 
24 
26 std::atomic<size_t> ArenaBlock::s_nactive;
27 
28 
40 ArenaBlock*
41 ArenaBlock::newBlock (size_t n, size_t elt_size, func_t* ctor)
42 {
43  static const size_t pageSize = sysconf (_SC_PAGESIZE);
44  size_t tot_size = n*elt_size + ArenaBlockBodyOffset;
45  // Round up to a multiple of pageSize.
46  size_t tot_size_rounded = (tot_size + (pageSize-1)) & ~(pageSize-1);
47  // Number of elements after rounding up.
48  size_t n_rounded = (tot_size_rounded - ArenaBlockBodyOffset) / elt_size;
49  assert (n_rounded >= n);
50  ArenaBlock* p = reinterpret_cast<ArenaBlock*>
51  (std::aligned_alloc (pageSize, tot_size_rounded));
52  ++s_nactive;
53  p->m_link = nullptr;
54  p->m_elt_size = elt_size;
55  p->m_size = n_rounded;
56  if (ctor) {
57  for (size_t i = 0; i < n_rounded; i++)
58  ctor (p->index (i, elt_size));
59  }
60  return p;
61 }
62 
63 
69 void ArenaBlock::destroy (ArenaBlock* p, func_t* dtor)
70 {
71  if (dtor) {
72  size_t elt_size = p->eltSize();
73  size_t n = p->size();
74  for (size_t i = 0; i < n; i++) {
75  dtor (p->index (i, elt_size));
76  }
77  }
78  --s_nactive;
79  std::free (p);
80 }
81 
82 
90 void
92 {
93  while (p) {
94  ArenaBlock* next = p->link();
95  destroy (p, dtor);
96  p = next;
97  }
98 }
99 
100 
111 {
112  while (*link) {
113  link = &(*link)->link();
114  }
115  *link = tail;
116 }
117 
118 
132  func_t* func,
133  size_t n)
134 {
135  if (!p) return;
136  size_t elt_size = p->eltSize();
137  if (n > p->size()) {
138  n = p->size();
139  }
140  while (1) {
141  for (size_t i = 0; i < n; i++) {
142  func (p->index (i, elt_size));
143  }
144  p = p->link();
145  if (!p) break;
146  n = p->size();
147  }
148 }
149 
150 
158 {
159  // The extra size_t is a guesstimate of malloc overhead.
160  return ArenaBlockBodyOffset + sizeof (size_t);
161 }
162 
163 
171 {
172  int stat = mprotect (this, m_size*m_elt_size+ArenaBlockBodyOffset,
173  PROT_READ);
174  if (stat) {
175  throw SG::ExcProtection (errno);
176  }
177 }
178 
179 
187 {
188  int stat = mprotect (this, m_size*m_elt_size+ArenaBlockBodyOffset,
189  PROT_READ + PROT_WRITE);
190  if (stat) {
191  throw SG::ExcProtection (errno);
192  }
193 }
194 
195 
204 {
205  for (; p; p = p->link()) {
206  p->protect();
207  }
208 }
209 
210 
219 {
220  for (; p; p = p->link()) {
221  p->unprotect();
222  }
223 }
224 
225 
226 } // namespace SG
SG::ExcProtection
Exception — Attempt to change memory protection failed.
Definition: Control/AthAllocators/AthAllocators/exceptions.h:43
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
SG::ArenaBlock::unprotect
void unprotect()
Write-enable this block.
Definition: ArenaBlock.cxx:186
SG
Forward declaration.
Definition: CaloCellPacker_400_500.h:32
SG::ArenaBlock::destroy
static void destroy(ArenaBlock *p, func_t *dtor)
Destroy a block.
Definition: ArenaBlock.cxx:69
tail
std::string tail(std::string s, const std::string &pattern)
tail of a string
Definition: computils.cxx:300
SG::ArenaBlock::applyList
static void applyList(ArenaBlock *p, func_t *func, size_t n)
Call a function on elements in a list of blocks.
Definition: ArenaBlock.cxx:131
SG::ArenaBlock::overhead
static size_t overhead()
Return the per-block memory overhead, in bytes.
Definition: ArenaBlock.cxx:157
SG::ArenaBlock::newBlock
static ArenaBlock * newBlock(size_t n, size_t elt_size, func_t *ctor)
Create a new block.
Definition: ArenaBlock.cxx:41
SG::ArenaBlock::appendList
static void appendList(ArenaBlock **headp, ArenaBlock *tail)
Concatenate two lists of blocks.
Definition: ArenaBlock.cxx:110
SG::ArenaBlock::unprotectList
static void unprotectList(ArenaBlock *p)
Write-enable all blocks in a list.
Definition: ArenaBlock.cxx:218
SG::ArenaBlock::link
ArenaBlock *& link()
Return the link pointer of the block.
fillPileUpNoiseLumi.next
next
Definition: fillPileUpNoiseLumi.py:52
lumiFormat.i
int i
Definition: lumiFormat.py:92
beamspotman.n
n
Definition: beamspotman.py:731
SG::ArenaBlock::m_size
size_t m_size
Number of elements in this block.
Definition: ArenaBlock.h:239
beamspotman.stat
stat
Definition: beamspotman.py:266
SG::ArenaBlock
A large memory block that gets carved into smaller uniform elements.
Definition: ArenaBlock.h:43
SG::ArenaBlock::s_nactive
static std::atomic< size_t > s_nactive
Global count of the number of blocks in use.
Definition: ArenaBlock.h:249
SG::ArenaBlock::m_elt_size
size_t m_elt_size
Size, in bytes, of each element in this block.
Definition: ArenaBlock.h:242
SG::ArenaBlock::protectList
static void protectList(ArenaBlock *p)
Write-protect all blocks in a list.
Definition: ArenaBlock.cxx:203
SG::ArenaBlock::protect
void protect()
Write-protect this block.
Definition: ArenaBlock.cxx:170
SG::ArenaBlock::destroyList
static void destroyList(ArenaBlock *p, func_t *dtor)
Destroy all blocks in a list.
Definition: ArenaBlock.cxx:91
exceptions.h
Exceptions that can be thrown from AthAllocators.
ArenaBlock.h
A large memory block that gets carved into smaller uniform elements. See Arena.h for an overview of t...