All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
allocator.h
Go to the documentation of this file.
1 //
2 // Copyright 2013 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 
25 #ifndef HBRALLOCATOR_H
26 #define HBRALLOCATOR_H
27 
28 #include "../version.h"
29 
30 namespace OpenSubdiv {
31 namespace OPENSUBDIV_VERSION {
32 
33 typedef void (*HbrMemStatFunction)(size_t bytes);
34 
39 template <typename T> class HbrAllocator {
40 
41 public:
42 
44  HbrAllocator(size_t *memorystat, int blocksize, void (*increment)(size_t bytes), void (*decrement)(size_t bytes), size_t elemsize = sizeof(T));
45 
47  ~HbrAllocator();
48 
50  T * Allocate();
51 
53  void Deallocate(T *);
54 
56  void Clear();
57 
58  void SetMemStatsIncrement(void (*increment)(size_t bytes)) { m_increment = increment; }
59 
60  void SetMemStatsDecrement(void (*decrement)(size_t bytes)) { m_decrement = decrement; }
61 
62 private:
63  size_t *m_memorystat;
64  const int m_blocksize;
65  int m_elemsize;
66  T** m_blocks;
67 
68  // Number of actually allocated blocks
69  int m_nblocks;
70 
71  // Size of the m_blocks array (which is NOT the number of actually
72  // allocated blocks)
73  int m_blockCapacity;
74 
75  int m_freecount;
76  T * m_freelist;
77 
78  // Memory statistics tracking routines
79  HbrMemStatFunction m_increment;
80  HbrMemStatFunction m_decrement;
81 };
82 
83 template <typename T>
84 HbrAllocator<T>::HbrAllocator(size_t *memorystat, int blocksize, void (*increment)(size_t bytes), void (*decrement)(size_t bytes), size_t elemsize)
85  : m_memorystat(memorystat), m_blocksize(blocksize), m_elemsize((int)elemsize), m_blocks(0), m_nblocks(0), m_blockCapacity(0), m_freecount(0), m_increment(increment), m_decrement(decrement) {
86 }
87 
88 template <typename T>
90  Clear();
91 }
92 
93 template <typename T>
95  for (int i = 0; i < m_nblocks; ++i) {
96  // Run the destructors (placement)
97  T* blockptr = m_blocks[i];
98  T* startblock = blockptr;
99  for (int j = 0; j < m_blocksize; ++j) {
100  blockptr->~T();
101  blockptr = (T*) ((char*) blockptr + m_elemsize);
102  }
103  free(startblock);
104  if (m_decrement) m_decrement(m_blocksize * m_elemsize);
105  *m_memorystat -= m_blocksize * m_elemsize;
106  }
107  free(m_blocks);
108  m_blocks = 0;
109  m_nblocks = 0;
110  m_blockCapacity = 0;
111  m_freecount = 0;
112  m_freelist = NULL;
113 }
114 
115 template <typename T>
116 T*
118  if (!m_freecount) {
119 
120  // Allocate a new block
121  T* block = (T*) malloc(m_blocksize * m_elemsize);
122  T* blockptr = block;
123  // Run the constructors on each element using placement new
124  for (int i = 0; i < m_blocksize; ++i) {
125  new (blockptr) T();
126  blockptr = (T*) ((char*) blockptr + m_elemsize);
127  }
128  if (m_increment) m_increment(m_blocksize * m_elemsize);
129  *m_memorystat += m_blocksize * m_elemsize;
130 
131  // Put the block's entries on the free list
132  blockptr = block;
133  for (int i = 0; i < m_blocksize - 1; ++i) {
134  T* next = (T*) ((char*) blockptr + m_elemsize);
135  blockptr->GetNext() = next;
136  blockptr = next;
137  }
138  blockptr->GetNext() = 0;
139  m_freelist = block;
140 
141  // Keep track of the newly allocated block
142  if (m_nblocks + 1 >= m_blockCapacity) {
143  m_blockCapacity = m_blockCapacity * 2;
144  if (m_blockCapacity < 1) m_blockCapacity = 1;
145  m_blocks = (T**) realloc(m_blocks, m_blockCapacity * sizeof(T*));
146  }
147  m_blocks[m_nblocks] = block;
148  m_nblocks++;
149  m_freecount += m_blocksize;
150  }
151  T* obj = m_freelist;
152  m_freelist = obj->GetNext();
153  obj->GetNext() = 0;
154  m_freecount--;
155  return obj;
156 }
157 
158 template <typename T>
159 void
161  assert(!obj->GetNext());
162  obj->GetNext() = m_freelist;
163  m_freelist = obj;
164  m_freecount++;
165 }
166 
167 } // end namespace OPENSUBDIV_VERSION
168 using namespace OPENSUBDIV_VERSION;
169 
170 } // end namespace OpenSubdiv
171 
172 #endif /* HBRALLOCATOR_H */
173 
void Clear()
Clear the allocator, deleting all allocated objects.
Definition: allocator.h:94
T * Allocate()
Create an allocated object.
Definition: allocator.h:117
void SetMemStatsIncrement(void(*increment)(size_t bytes))
Definition: allocator.h:58
void Deallocate(T *)
Return an allocated object to the block allocator.
Definition: allocator.h:160
void(* HbrMemStatFunction)(size_t bytes)
Definition: allocator.h:33
HbrAllocator(size_t *memorystat, int blocksize, void(*increment)(size_t bytes), void(*decrement)(size_t bytes), size_t elemsize=sizeof(T))
Constructor.
Definition: allocator.h:84
void SetMemStatsDecrement(void(*decrement)(size_t bytes))
Definition: allocator.h:60