Removed old tree unit test
[libcds.git] / tests / test-hdr / misc / michael_allocator.h
1 /*
2     This file is a part of libcds - Concurrent Data Structures library
3
4     (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
5
6     Source code repo: http://github.com/khizmax/libcds/
7     Download: http://sourceforge.net/projects/libcds/files/
8     
9     Redistribution and use in source and binary forms, with or without
10     modification, are permitted provided that the following conditions are met:
11
12     * Redistributions of source code must retain the above copyright notice, this
13       list of conditions and the following disclaimer.
14
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.
18
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.     
29 */
30
31 #include <cds/memory/michael/allocator.h>
32 #include <iostream>
33
34 namespace misc {
35     namespace ma = cds::memory::michael;
36
37     typedef ma::Heap<
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;
42
43     typedef ma::Heap<
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>
47     >  t_MichaelHeap_Stat;
48
49     typedef ma::summary_stat            summary_stat;
50
51     extern t_MichaelHeap_NoStat  s_MichaelHeap_NoStat;
52     extern t_MichaelHeap_Stat    s_MichaelHeap_Stat;
53
54     template <typename T>
55     class MichaelHeap_NoStat
56     {
57     public:
58         typedef T value_type;
59         typedef T * pointer;
60
61         enum {
62             alignment = 1
63         };
64
65
66         pointer allocate( size_t nSize, const void * /*pHint*/ )
67         {
68             return reinterpret_cast<pointer>( s_MichaelHeap_NoStat.alloc( sizeof(T) * nSize ) );
69         }
70
71         void deallocate( pointer p, size_t /*nCount*/ )
72         {
73             s_MichaelHeap_NoStat.free( p );
74         }
75
76         static void stat(summary_stat& s)
77         {
78             s_MichaelHeap_NoStat.summaryStat(s);
79         }
80     };
81
82     template <typename T>
83     class std_allocator: public std::allocator<T>
84     {
85     public:
86         enum {
87             alignment = 1
88         };
89
90         static void stat(summary_stat& /*s*/)
91         {}
92     };
93
94     template <typename T>
95     class MichaelHeap_Stat
96     {
97     public:
98         typedef T value_type;
99         typedef T * pointer;
100
101         enum {
102             alignment = 1
103         };
104
105         pointer allocate( size_t nSize, const void * /*pHint*/ )
106         {
107             return reinterpret_cast<pointer>( s_MichaelHeap_Stat.alloc( sizeof(T) * nSize ) );
108         }
109
110         void deallocate( pointer p, size_t /*nCount*/ )
111         {
112             s_MichaelHeap_Stat.free( p );
113         }
114
115         static void stat(summary_stat& s)
116         {
117             s_MichaelHeap_Stat.summaryStat(s);
118         }
119     };
120
121     template <typename T, size_t ALIGN>
122     class MichaelAlignHeap_NoStat
123     {
124     public:
125         typedef T value_type;
126         typedef T * pointer;
127
128         enum {
129             alignment = ALIGN
130         };
131
132         pointer allocate( size_t nSize, const void * /*pHint*/ )
133         {
134             return reinterpret_cast<pointer>( s_MichaelHeap_NoStat.alloc_aligned( sizeof(T) * nSize, ALIGN ) );
135         }
136
137         void deallocate( pointer p, size_t /*nCount*/ )
138         {
139             s_MichaelHeap_NoStat.free_aligned( p );
140         }
141
142         static void stat(summary_stat& s)
143         {
144             s_MichaelHeap_NoStat.summaryStat(s);
145         }
146     };
147
148     template <typename T, size_t ALIGN>
149     class MichaelAlignHeap_Stat {
150     public:
151         typedef T value_type;
152         typedef T * pointer;
153
154         enum {
155             alignment = ALIGN
156         };
157
158         pointer allocate( size_t nSize, const void * /*pHint*/ )
159         {
160             return reinterpret_cast<pointer>( s_MichaelHeap_Stat.alloc_aligned( sizeof(T) * nSize, ALIGN ) );
161         }
162
163         void deallocate( pointer p, size_t /*nCount*/ )
164         {
165             s_MichaelHeap_Stat.free_aligned( p );
166         }
167
168         static void stat(summary_stat& s)
169         {
170             s_MichaelHeap_Stat.summaryStat(s);
171         }
172     };
173
174     template <typename T, size_t ALIGN>
175     class system_aligned_allocator
176     {
177     public:
178         typedef T value_type;
179         typedef T * pointer;
180
181         enum {
182             alignment = ALIGN
183         };
184
185         pointer allocate( size_t nSize, const void * /*pHint*/ )
186         {
187             return reinterpret_cast<pointer>( cds::OS::aligned_malloc( sizeof(T) * nSize, ALIGN ) );
188         }
189
190         void deallocate( pointer p, size_t /*nCount*/ )
191         {
192             cds::OS::aligned_free( p );
193         }
194
195         static void stat(summary_stat& /*s*/)
196         {}
197     };
198
199     static inline std::ostream& operator <<(std::ostream& os, const summary_stat& s)
200     {
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
221             << std::endl;
222
223         return os;
224     }
225 }