LSSTApplications  1.1.2+25,10.0+13,10.0+132,10.0+133,10.0+224,10.0+41,10.0+8,10.0-1-g0f53050+14,10.0-1-g4b7b172+19,10.0-1-g61a5bae+98,10.0-1-g7408a83+3,10.0-1-gc1e0f5a+19,10.0-1-gdb4482e+14,10.0-11-g3947115+2,10.0-12-g8719d8b+2,10.0-15-ga3f480f+1,10.0-2-g4f67435,10.0-2-gcb4bc6c+26,10.0-28-gf7f57a9+1,10.0-3-g1bbe32c+14,10.0-3-g5b46d21,10.0-4-g027f45f+5,10.0-4-g86f66b5+2,10.0-4-gc4fccf3+24,10.0-40-g4349866+2,10.0-5-g766159b,10.0-5-gca2295e+25,10.0-6-g462a451+1
LSSTDataManagementBasePackage
Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes | Friends | List of all members
lsst::ap::utils::Arena< T > Class Template Reference

#include <Arena.h>

Public Member Functions

 Arena (size_t blockCapacity=262144/sizeof(T))
 
 ~Arena ()
 
void destroy (T *ptr)
 
size_t capacity () const
 
size_t getNumBytes () const
 
size_t getBlockCapacity () const
 

Private Member Functions

 BOOST_STATIC_ASSERT ((ALIGN &(ALIGN-1))==0)
 
 Arena (Arena const &)
 
Arenaoperator= (Arena const &)
 
void_alloc ()
 
void _dealloc (void *ptr)
 
void _grow ()
 
friend void (::operator delete<>)(void *
 

Static Private Member Functions

static unsigned char * _align (unsigned char *p)
 

Private Attributes

std::vector< unsigned char * > _blocks
 List of memory blocks. More...
 
std::vector< std::vector< bool > > _masks
 
size_t const _blockCapacity
 Capacity of a memory block. More...
 
size_t _nFree
 Number of free elements. More...
 
unsigned char * _free
 Head of linked free-list, 0 if arena is full. More...
 

Static Private Attributes

static const size_t ALIGN = 16
 
static const size_t SIZE = (sizeof(T) + ALIGN - 1) & ~(ALIGN - 1)
 

Friends

voidoperator new) (size_t, lsst::ap::utils::Arena< T > &)
 

Detailed Description

template<typename T>
class lsst::ap::utils::Arena< T >

A free-list based single-threaded arena allocator for objects of class T.

The arena grows in blocks of a run-time specified capacity, and never shrinks during the lifetime of the arena. All blocks are allocated with malloc(), and are freed when the arena is destroyed. Note that destroying the arena will also call the destructors of any live objects in the arena.
This class is quite low-level and is intended for use in performance critical code only.

Definition at line 44 of file Arena.h.

Constructor & Destructor Documentation

template<typename T >
lsst::ap::utils::Arena< T >::Arena ( size_t  blockCapacity = 262144/sizeof(T))

Creates a new Arena for objects of type T. The arena allocates memory from the system in blocks, each of which is large enough to contain blockCapacity objects.

Definition at line 41 of file Arena.cc.

41  :
42  _blocks(),
43  _masks(),
44  _blockCapacity(blockCapacity),
45  _nFree(0),
46  _free(0)
47 {
48  if (blockCapacity == 0) {
49  throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
50  "Cannot create Arena with 0 capacity");
51  }
52  _grow();
53 }
unsigned char * _free
Head of linked free-list, 0 if arena is full.
Definition: Arena.h:102
size_t _nFree
Number of free elements.
Definition: Arena.h:101
size_t const _blockCapacity
Capacity of a memory block.
Definition: Arena.h:100
std::vector< std::vector< bool > > _masks
Definition: Arena.h:96
std::vector< unsigned char * > _blocks
List of memory blocks.
Definition: Arena.h:95
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
template<typename T >
lsst::ap::utils::Arena< T >::~Arena ( )

Definition at line 56 of file Arena.cc.

56  {
57  typedef std::vector<unsigned char *>::iterator Iter;
58 
59  if (_nFree == 0) {
60  assert(_free == 0 &&
61  "No free elements, but free list head is non-null");
62  // call destructor for every element of every block
63  for (Iter i = _blocks.begin(), e = _blocks.end(); i != e; ++i) {
64  unsigned char *block = _align(*i);
65  unsigned char *blockEnd = block + _blockCapacity*SIZE;
66  for (; block < blockEnd; block += SIZE) {
67  reinterpret_cast<T *>(block)->~T();
68  }
69  }
70  } else if (_nFree < _blocks.size()*_blockCapacity) {
71  assert(_free != 0 &&
72  "Free count is non zero, but free list head is null");
73  // need to call destructor for each allocated entry -
74  // first compute free bits for every block.
75  std::sort(_blocks.begin(), _blocks.end());
76  unsigned char *ptr = _free;
77  while (ptr != 0) {
78  // figure out which block ptr is from and mark the element free
79  Iter b = std::upper_bound(_blocks.begin(), _blocks.end(), ptr);
80  assert(b != _blocks.begin() &&
81  "Free list contains pointer not belonging to arena");
82  --b;
83  unsigned char *ab = _align(*b);
84  assert((ptr - ab) % SIZE == 0 &&
85  "Free list contains unaligned pointer");
86  _masks[b - _blocks.begin()][(ptr - ab)/SIZE] = true;
87  --_nFree;
88  ptr = *reinterpret_cast<unsigned char **>(ptr);
89  }
90  assert(_nFree == 0 && "Free list does not contain all free elements");
91  // free any element not flagged as free in its occupancy mask
92  for (size_t i = 0; i < _blocks.size(); ++i) {
93  unsigned char *block = _align(_blocks[i]);
94  std::vector<bool> const & free = _masks[i];
95  for (size_t j = 0; j < _blocks.size(); block += SIZE, ++j) {
96  if (!free[j]) {
97  reinterpret_cast<T *>(block)->~T();
98  }
99  }
100  }
101  } else {
102  assert(_nFree == _blocks.size()*_blockCapacity &&
103  "Number of free elements exceeds arena capacity");
104  }
105  // free the memory for each block
106  for (Iter i = _blocks.begin(), e = _blocks.end(); i != e; ++i) {
107  std::free(*i);
108  *i = 0;
109  }
110 }
unsigned char * _free
Head of linked free-list, 0 if arena is full.
Definition: Arena.h:102
static unsigned char * _align(unsigned char *p)
Definition: Arena.cc:221
size_t _nFree
Number of free elements.
Definition: Arena.h:101
size_t const _blockCapacity
Capacity of a memory block.
Definition: Arena.h:100
std::vector< std::vector< bool > > _masks
Definition: Arena.h:96
std::vector< unsigned char * > _blocks
List of memory blocks.
Definition: Arena.h:95
static const size_t SIZE
Definition: Arena.h:81
afw::table::Key< double > b
template<typename T>
lsst::ap::utils::Arena< T >::Arena ( Arena< T > const &  )
private

Member Function Documentation

template<typename T >
unsigned char * lsst::ap::utils::Arena< T >::_align ( unsigned char *  p)
inlinestaticprivate

Definition at line 221 of file Arena.cc.

221  {
222  return reinterpret_cast<unsigned char *>(
223  reinterpret_cast<size_t>(ptr + ALIGN) & ~(ALIGN - 1));
224 }
static const size_t ALIGN
Definition: Arena.h:80
template<typename T >
void * lsst::ap::utils::Arena< T >::_alloc ( )
inlineprivate

Allocates and returns a pointer to a memory region large enough to hold a single object of type T.

Definition at line 116 of file Arena.cc.

116  {
117  if (_free == 0) {
118  _grow();
119  }
120  unsigned char *next = _free;
121  _free = *reinterpret_cast<unsigned char **>(next);
122  --_nFree;
123  return next;
124 }
unsigned char * _free
Head of linked free-list, 0 if arena is full.
Definition: Arena.h:102
Edge * next
Definition: ImageUtils.cc:91
size_t _nFree
Number of free elements.
Definition: Arena.h:101
template<typename T >
void lsst::ap::utils::Arena< T >::_dealloc ( void ptr)
inlineprivate

Frees the memory at the given address.

Definition at line 129 of file Arena.cc.

129  {
130  unsigned char *next = static_cast<unsigned char *>(ptr);
131  *reinterpret_cast<unsigned char **>(next) = _free;
132  _free = next;
133  ++_nFree;
134 }
unsigned char * _free
Head of linked free-list, 0 if arena is full.
Definition: Arena.h:102
Edge * next
Definition: ImageUtils.cc:91
size_t _nFree
Number of free elements.
Definition: Arena.h:101
template<typename T >
void lsst::ap::utils::Arena< T >::_grow ( )
private

Definition at line 167 of file Arena.cc.

167  {
168  // pre-allocate space in block and block mask list
169  if (_blocks.size() == _blocks.capacity()) {
170  if (_blocks.size() == _blocks.max_size()) {
171  throw std::length_error("cannot expand vector: "
172  "max_size() would be exceeded");
173  }
174  std::vector<unsigned char *>::size_type c = 2*_blocks.capacity();
175  if (c == 0) {
176  ++ c;
177  }
178  if (c < _blocks.capacity() || c > _blocks.max_size()) {
179  c = _blocks.max_size();
180  }
181  _blocks.reserve(c);
182  }
183  if (_masks.size() == _masks.capacity()) {
184  if (_masks.size() == _masks.max_size()) {
185  throw std::length_error("cannot expand vector: "
186  "max_size() would be exceeded");
187  }
188  std::vector<std::vector<bool> >::size_type c = 2*_masks.capacity();
189  if (c == 0) {
190  ++c;
191  }
192  if (c < _masks.capacity() || c > _masks.max_size()) {
193  c = _masks.max_size();
194  }
195  _masks.reserve(c);
196  }
197  std::vector<bool> mask(_blockCapacity, false);
198  // allocate another block
199  unsigned char *block = static_cast<unsigned char *>(
200  std::malloc(_blockCapacity*SIZE + ALIGN));
201  if (block == 0) {
202  throw std::bad_alloc();
203  }
204  // what follows will not throw so long as the std::vector default
205  // constructor does not throw
206  _masks.push_back(std::vector<bool>());
207  std::swap(_masks.back(), mask);
208  // initialize free-list
209  unsigned char *item = _align(block);
210  for (size_t i = 0; i < _blockCapacity - 1; ++i, item += SIZE) {
211  *reinterpret_cast<unsigned char **>(item) = item + SIZE;
212  }
213  *reinterpret_cast<unsigned char **>(item) = 0;
214  // set _free to head of free-list and store new block pointer
215  _free = _align(block);
217  _blocks.push_back(block);
218 }
unsigned char * _free
Head of linked free-list, 0 if arena is full.
Definition: Arena.h:102
static unsigned char * _align(unsigned char *p)
Definition: Arena.cc:221
void swap(ImageBase< PixelT > &a, ImageBase< PixelT > &b)
Definition: Image.cc:291
size_t _nFree
Number of free elements.
Definition: Arena.h:101
size_t const _blockCapacity
Capacity of a memory block.
Definition: Arena.h:100
std::vector< std::vector< bool > > _masks
Definition: Arena.h:96
std::vector< unsigned char * > _blocks
List of memory blocks.
Definition: Arena.h:95
static const size_t SIZE
Definition: Arena.h:81
static const size_t ALIGN
Definition: Arena.h:80
template<typename T>
lsst::ap::utils::Arena< T >::BOOST_STATIC_ASSERT ( (ALIGN &(ALIGN-1))  = =0)
private
template<typename T >
size_t lsst::ap::utils::Arena< T >::capacity ( ) const
inline

Returns the total number of objects that can fit in the arena.

Definition at line 147 of file Arena.cc.

147  {
148  return _blockCapacity*_blocks.size();
149 }
size_t const _blockCapacity
Capacity of a memory block.
Definition: Arena.h:100
std::vector< unsigned char * > _blocks
List of memory blocks.
Definition: Arena.h:95
template<typename T>
void lsst::ap::utils::Arena< T >::destroy ( T *  ptr)
inline

Destroys and frees the object at the given address.

Definition at line 139 of file Arena.cc.

139  {
140  ptr->~T();
141  _dealloc(ptr);
142 }
void _dealloc(void *ptr)
Definition: Arena.cc:129
template<typename T >
size_t lsst::ap::utils::Arena< T >::getBlockCapacity ( ) const
inline

Returns the number of objects that fit in a single arena block.

Definition at line 161 of file Arena.cc.

161  {
162  return _blockCapacity;
163 }
size_t const _blockCapacity
Capacity of a memory block.
Definition: Arena.h:100
template<typename T >
size_t lsst::ap::utils::Arena< T >::getNumBytes ( ) const
inline

Returns the number of bytes in the arena.

Definition at line 154 of file Arena.cc.

154  {
155  return capacity()*SIZE;
156 }
size_t capacity() const
Definition: Arena.cc:147
static const size_t SIZE
Definition: Arena.h:81
template<typename T>
Arena& lsst::ap::utils::Arena< T >::operator= ( Arena< T > const &  )
private
template<typename T>
lsst::ap::utils::Arena< T >::void ( ::operator delete<>  )
private

Friends And Related Function Documentation

template<typename T>
void* operator new) ( size_t  ,
lsst::ap::utils::Arena< T > &   
)
friend

Member Data Documentation

template<typename T>
size_t const lsst::ap::utils::Arena< T >::_blockCapacity
private

Capacity of a memory block.

Definition at line 100 of file Arena.h.

template<typename T>
std::vector<unsigned char *> lsst::ap::utils::Arena< T >::_blocks
private

List of memory blocks.

Definition at line 95 of file Arena.h.

template<typename T>
unsigned char* lsst::ap::utils::Arena< T >::_free
private

Head of linked free-list, 0 if arena is full.

Definition at line 102 of file Arena.h.

template<typename T>
std::vector<std::vector<bool> > lsst::ap::utils::Arena< T >::_masks
private

Per-block free bits - used only in the arena destructor, but is pre-allocated to avoid std::bad_alloc therein.

Definition at line 96 of file Arena.h.

template<typename T>
size_t lsst::ap::utils::Arena< T >::_nFree
private

Number of free elements.

Definition at line 101 of file Arena.h.

template<typename T>
const size_t lsst::ap::utils::Arena< T >::ALIGN = 16
staticprivate

Definition at line 80 of file Arena.h.

template<typename T>
const size_t lsst::ap::utils::Arena< T >::SIZE = (sizeof(T) + ALIGN - 1) & ~(ALIGN - 1)
staticprivate

Definition at line 81 of file Arena.h.


The documentation for this class was generated from the following files: