Move libcds 1.6.0 from SVN
[libcds.git] / cds / memory / michael / options.h
1 //$$CDS-header$$
2
3 #ifndef __CDS_MEMORY_MICHAEL_OPTIONS_H
4 #define __CDS_MEMORY_MICHAEL_OPTIONS_H
5
6 /*
7     Options for Michael allocator
8     Source:
9         [2004] Maged Michael "Scalable Lock-Free Dynamic Memory Allocation"
10
11     Editions:
12         2011.01.23 khizmax  Created
13 */
14
15 #include <cds/opt/options.h>
16
17 namespace cds { namespace memory { namespace michael {
18
19     /// Options related for Michael's allocator \ref Heap
20     namespace opt {
21         using namespace cds::opt;
22
23         /// Option setter specifies system topology
24         /**
25             See cds::OS::Win32::topology for interface example.
26
27             Default type: \p cds::OS::topology selects appropriate implementation for target system.
28         */
29         template <typename TOPOLOGY>
30         struct sys_topology {
31             //@cond
32             template<class BASE> struct pack: public BASE
33             {
34                 typedef TOPOLOGY sys_topology;
35             };
36             //@endcond
37         };
38
39         /// Option setter specifies system heap for large blocks
40         /**
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.
45
46             Available \p HEAP implementations:
47                 - malloc_heap
48         */
49         template <typename HEAP>
50         struct system_heap
51         {
52             //@cond
53             template<class BASE> struct pack: public BASE
54             {
55                 typedef HEAP system_heap;
56             };
57             //@endcond
58         };
59
60         /// Option setter specifies internal aligned heap
61         /**
62             This heap is used by Michael's allocator for obtaining aligned memory.
63
64             Available \p HEAP implementations:
65                 - aligned_malloc_heap
66         */
67         template <typename HEAP>
68         struct aligned_heap {
69             //@cond
70             template<class BASE> struct pack: public BASE
71             {
72                 typedef HEAP aligned_heap;
73             };
74             //@endcond
75         };
76
77         /// Option setter specifies page heap
78         /**
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
83
84             Available \p HEAP implementations:
85                 - page_allocator
86                 - page_cached_allocator
87         */
88         template <typename HEAP>
89         struct page_heap {
90             //@cond
91             template<class BASE> struct pack: public BASE
92             {
93                 typedef HEAP page_heap;
94             };
95             //@endcond
96         };
97
98         /// Option setter specifies size-class selector
99         /**
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.
103
104             Available \p Type implementation:
105                 - default_sizeclass_selector
106         */
107         template <typename Type>
108         struct sizeclass_selector {
109             //@cond
110             template<class BASE> struct pack: public BASE
111             {
112                 typedef Type sizeclass_selector;
113             };
114             //@endcond
115         };
116
117         /// Option setter specifies free-list of superblock descriptor
118         /**
119             Available \p Type implementations:
120                 - free_list_locked
121         */
122         template <typename Type>
123         struct free_list {
124             //@cond
125             template<class BASE> struct pack: public BASE
126             {
127                 typedef Type free_list;
128             };
129             //@endcond
130         };
131
132         /// Option setter specifies partial list of superblocks
133         /**
134             Available \p Type implementations:
135                 - partial_list_locked
136         */
137         template <typename Type>
138         struct partial_list {
139             //@cond
140             template<class BASE> struct pack: public BASE
141             {
142                 typedef Type partial_list;
143             };
144             //@endcond
145         };
146
147         /// Option setter for processor heap statistics
148         /**
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.
153
154             Available \p Type implementations:
155                 - \ref procheap_atomic_stat
156                 - \ref procheap_empty_stat
157
158             For interface of type \p Type see \ref procheap_atomic_stat.
159         */
160         template <typename Type>
161         struct procheap_stat {
162             //@cond
163             template <class BASE> struct pack: public BASE
164             {
165                 typedef Type procheap_stat;
166             };
167             //@endcond
168         };
169
170         /// Option setter for OS-allocated memory
171         /**
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).
176
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.
180
181             Available \p Type implementations:
182                 - \ref os_allocated_atomic
183                 - \ref os_allocated_empty
184         */
185         template <typename Type>
186         struct os_allocated_stat {
187             //@cond
188             template <class BASE> struct pack: public BASE
189             {
190                 typedef Type os_allocated_stat;
191             };
192             //@endcond
193         };
194
195         /// Option setter for bounds checking
196         /**
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:
199
200             \code
201             class bound_checker
202             {
203             public:
204                 enum {
205                     trailer_size = numeric_const
206                 };
207
208                 void make_trailer( void * pStartArea, void * pEndBlock, size_t nAllocSize );
209                 bool check_bounds( void * pStartArea, void * pEndBlock, size_t nBlockSize );
210             }
211             \endcode
212
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).
221
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
227
228             The function can:
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
232
233             The library provides the following predefined bound checkers, i.e they are possible values of \p Type
234             template argument:
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.
240         */
241         template <typename Type>
242         struct check_bounds {
243             //@cond
244             template <class BASE> struct pack: public BASE
245             {
246                 typedef Type check_bounds;
247             };
248             //@endcond
249         };
250     }
251
252 }}} // namespace cds::memory::michael
253
254 #endif // #ifndef __CDS_MEMORY_MICHAEL_OPTIONS_H