3 #ifndef __CDS_MEMORY_MICHAEL_OPTIONS_H
4 #define __CDS_MEMORY_MICHAEL_OPTIONS_H
7 Options for Michael allocator
9 [2004] Maged Michael "Scalable Lock-Free Dynamic Memory Allocation"
12 2011.01.23 khizmax Created
15 #include <cds/opt/options.h>
17 namespace cds { namespace memory { namespace michael {
19 /// Options related for Michael's allocator \ref Heap
21 using namespace cds::opt;
23 /// Option setter specifies system topology
25 See cds::OS::Win32::topology for interface example.
27 Default type: \p cds::OS::topology selects appropriate implementation for target system.
29 template <typename TOPOLOGY>
32 template<class BASE> struct pack: public BASE
34 typedef TOPOLOGY sys_topology;
39 /// Option setter specifies system heap for large blocks
41 If the block size requested is more that Michael's allocator upper limit
42 then an allocator provided by \p system_heap option is called.
43 By default, Michael's allocator can maintain blocks up to 64K bytes length;
44 for blocks larger than 64K the allocator defined by this option is used.
46 Available \p HEAP implementations:
49 template <typename HEAP>
53 template<class BASE> struct pack: public BASE
55 typedef HEAP system_heap;
60 /// Option setter specifies internal aligned heap
62 This heap is used by Michael's allocator for obtaining aligned memory.
64 Available \p HEAP implementations:
67 template <typename HEAP>
70 template<class BASE> struct pack: public BASE
72 typedef HEAP aligned_heap;
77 /// Option setter specifies page heap
79 This heap is used by Michael's allocator for superblock allocation.
80 The size of superblock is:
81 - 64K - for small blocks
82 - 1M - for other blocks
84 Available \p HEAP implementations:
86 - page_cached_allocator
88 template <typename HEAP>
91 template<class BASE> struct pack: public BASE
93 typedef HEAP page_heap;
98 /// Option setter specifies size-class selector
100 The size-class selector determines the best size-class for requested block size,
101 i.e. it specifies allocation granularity.
102 In fact, it selects superblock descriptor within processor heap.
104 Available \p Type implementation:
105 - default_sizeclass_selector
107 template <typename Type>
108 struct sizeclass_selector {
110 template<class BASE> struct pack: public BASE
112 typedef Type sizeclass_selector;
117 /// Option setter specifies free-list of superblock descriptor
119 Available \p Type implementations:
122 template <typename Type>
125 template<class BASE> struct pack: public BASE
127 typedef Type free_list;
132 /// Option setter specifies partial list of superblocks
134 Available \p Type implementations:
135 - partial_list_locked
137 template <typename Type>
138 struct partial_list {
140 template<class BASE> struct pack: public BASE
142 typedef Type partial_list;
147 /// Option setter for processor heap statistics
149 The option specifies a type for gathering internal processor heap statistics.
150 The processor heap statistics is gathered on per processor basis.
151 Large memory block (more than 64K) allocated directly from OS does not fall into these statistics.
152 For OS-allocated memory block see \ref os_allocated_stat option.
154 Available \p Type implementations:
155 - \ref procheap_atomic_stat
156 - \ref procheap_empty_stat
158 For interface of type \p Type see \ref procheap_atomic_stat.
160 template <typename Type>
161 struct procheap_stat {
163 template <class BASE> struct pack: public BASE
165 typedef Type procheap_stat;
170 /// Option setter for OS-allocated memory
172 The option specifies a type for gathering internal statistics of
173 large (OS-allocated) memory blocks that is too big to maintain by Michael's heap
174 (with default \ref sizeclass_selector, the block that large than 64K is not
175 maintained by Michael's heap and passed directly to system allocator).
177 Note that OS-allocated memory statistics does not include memory allocation
178 for heap's internal purposes. Only direct call of \p alloc or \p alloc_aligned
179 for large memory block is counted.
181 Available \p Type implementations:
182 - \ref os_allocated_atomic
183 - \ref os_allocated_empty
185 template <typename Type>
186 struct os_allocated_stat {
188 template <class BASE> struct pack: public BASE
190 typedef Type os_allocated_stat;
195 /// Option setter for bounds checking
197 This option defines a strategy to check upper memory boundary of allocated blocks.
198 \p Type defines a class for bound checking with following interface:
205 trailer_size = numeric_const
208 void make_trailer( void * pStartArea, void * pEndBlock, size_t nAllocSize );
209 bool check_bounds( void * pStartArea, void * pEndBlock, size_t nBlockSize );
213 Before allocating a memory block of size N, the heap adds the \p trailer_size to N and really it
214 allocates N + trailer_size bytes. Then, the heap calls \p make_trailer function of bound checker with arguments:
215 - \p pStartArea - start of allocated block
216 - \p pEndBlock - the first byte after really allocated block; \code pEndBlock - pStartArea >= N + trailer_size \endcode
217 - \p nAllocSize - requested size in bytes (i.e. N)
218 So, \p make_trailer function can place some predefined value called bound mark of any type, for example, int64,
219 on address pStartArea + nAllocSize, and store real allocated block size N to pEndBlock - sizeof(size_t).
220 In this example, \p trailer_size constant is equal sizeof(int64) + sizeof(size_t).
222 Before the memory block previously allocated is deallocating, the \p check_bounds function is called.
223 The function has similar signature:
224 - \p pStartArea - start of allocated block (like \p make_trailer fist argument)
225 - \p pEndBlock - the first byte after allocated block (like \p make_trailer second argument)
226 - \p nBlockSize - real allocated block size, not equal to \p nAllocSize argument of \p make_trailer
229 - calculate real allocated block size: \code N = *reinterpret_cast<size_t>(pEndBlock - sizeof(size_t)) \endcode
230 - check whether the bound mark is unchanged: \code *reinterpret_cast<int64>(pStartArea + N) == bound_mark \endcode
231 - if it is not equal - make assertion
233 The library provides the following predefined bound checkers, i.e they are possible values of \p Type
235 \li cds::opt::none - no bound checking is performed (default)
236 \li michael::debug_bound_checking - an assertion is thrown when memory bound violation is detected.
237 This option is acceptable only in debug mode. For release mode it is equal to cds::opt::none.
238 \li michael::strong_bound_checking - an assertion is thrown in debug mode if memory bound violation is detected;
239 an exception is thrown in release mode.
241 template <typename Type>
242 struct check_bounds {
244 template <class BASE> struct pack: public BASE
246 typedef Type check_bounds;
252 }}} // namespace cds::memory::michael
254 #endif // #ifndef __CDS_MEMORY_MICHAEL_OPTIONS_H