2 This file is a part of libcds - Concurrent Data Structures library
4 (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
6 Source code repo: http://github.com/khizmax/libcds/
7 Download: http://sourceforge.net/projects/libcds/files/
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
12 * Redistributions of source code must retain the above copyright notice, this
13 list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright notice,
16 this list of conditions and the following disclaimer in the documentation
17 and/or other materials provided with the distribution.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <cds/memory/michael/allocator.h>
35 namespace ma = cds::memory::michael;
38 ma::opt::procheap_stat<ma::procheap_empty_stat>,
39 ma::opt::os_allocated_stat<ma::os_allocated_empty>,
40 ma::opt::check_bounds<ma::debug_bound_checking>
41 > t_MichaelHeap_NoStat;
44 ma::opt::procheap_stat<ma::procheap_atomic_stat >,
45 ma::opt::os_allocated_stat<ma::os_allocated_atomic >,
46 ma::opt::check_bounds<ma::debug_bound_checking>
49 typedef ma::summary_stat summary_stat;
51 extern t_MichaelHeap_NoStat s_MichaelHeap_NoStat;
52 extern t_MichaelHeap_Stat s_MichaelHeap_Stat;
55 class MichaelHeap_NoStat
66 pointer allocate( size_t nSize, const void * /*pHint*/ )
68 return reinterpret_cast<pointer>( s_MichaelHeap_NoStat.alloc( sizeof(T) * nSize ) );
71 void deallocate( pointer p, size_t /*nCount*/ )
73 s_MichaelHeap_NoStat.free( p );
76 static void stat(summary_stat& s)
78 s_MichaelHeap_NoStat.summaryStat(s);
83 class std_allocator: public std::allocator<T>
90 static void stat(summary_stat& /*s*/)
95 class MichaelHeap_Stat
105 pointer allocate( size_t nSize, const void * /*pHint*/ )
107 return reinterpret_cast<pointer>( s_MichaelHeap_Stat.alloc( sizeof(T) * nSize ) );
110 void deallocate( pointer p, size_t /*nCount*/ )
112 s_MichaelHeap_Stat.free( p );
115 static void stat(summary_stat& s)
117 s_MichaelHeap_Stat.summaryStat(s);
121 template <typename T, size_t ALIGN>
122 class MichaelAlignHeap_NoStat
125 typedef T value_type;
132 pointer allocate( size_t nSize, const void * /*pHint*/ )
134 return reinterpret_cast<pointer>( s_MichaelHeap_NoStat.alloc_aligned( sizeof(T) * nSize, ALIGN ) );
137 void deallocate( pointer p, size_t /*nCount*/ )
139 s_MichaelHeap_NoStat.free_aligned( p );
142 static void stat(summary_stat& s)
144 s_MichaelHeap_NoStat.summaryStat(s);
148 template <typename T, size_t ALIGN>
149 class MichaelAlignHeap_Stat {
151 typedef T value_type;
158 pointer allocate( size_t nSize, const void * /*pHint*/ )
160 return reinterpret_cast<pointer>( s_MichaelHeap_Stat.alloc_aligned( sizeof(T) * nSize, ALIGN ) );
163 void deallocate( pointer p, size_t /*nCount*/ )
165 s_MichaelHeap_Stat.free_aligned( p );
168 static void stat(summary_stat& s)
170 s_MichaelHeap_Stat.summaryStat(s);
174 template <typename T, size_t ALIGN>
175 class system_aligned_allocator
178 typedef T value_type;
185 pointer allocate( size_t nSize, const void * /*pHint*/ )
187 return reinterpret_cast<pointer>( cds::OS::aligned_malloc( sizeof(T) * nSize, ALIGN ) );
190 void deallocate( pointer p, size_t /*nCount*/ )
192 cds::OS::aligned_free( p );
195 static void stat(summary_stat& /*s*/)
199 static inline std::ostream& operator <<(std::ostream& os, const summary_stat& s)
201 os << "\t alloc from active: " << s.nAllocFromActive << "\n"
202 << "\t alloc from partial: " << s.nAllocFromPartial << "\n"
203 << "\t alloc from new: " << s.nAllocFromNew << "\n"
204 << "\t free call count: " << s.nFreeCount << "\n"
205 << "\t superblock allocated: " << s.nPageAllocCount << "\n"
206 << "\t superblock deallocated: " << s.nPageDeallocCount << "\n"
207 << "\t superblock desc allocated: " << s.nDescAllocCount << "\n"
208 << "\t superblock full desc: " << s.nDescFull << "\n"
209 << "\t total allocated bytes: " << s.nBytesAllocated << "\n"
210 << "\t total deallocated bytes: " << s.nBytesDeallocated << "\n"
211 << "\tOS-allocated large blocks\n"
212 << "\t alloc call count: " << s.nSysAllocCount << "\n"
213 << "\t free call count: " << s.nSysFreeCount << "\n"
214 << "\t total allocated bytes: " << s.nSysBytesAllocated << "\n"
215 << "\t total deallocated bytes: " << s.nSysBytesDeallocated << "\n"
216 << "\tCAS contention indicators\n"
217 << "\t updating active field of active block: " << s.nActiveDescCASFailureCount << "\n"
218 << "\t updating anchor field of active block: " << s.nActiveAnchorCASFailureCount << "\n"
219 << "\tupdating active field of partial block: " << s.nPartialDescCASFailureCount << "\n"
220 << "\tupdating anchor field of partial block: " << s.nPartialAnchorCASFailureCount