7ef01a619bb178daefc15e0dff582363c0b4f413
[libcds.git] / tests / unit / alloc / michael_allocator.h
1 //$$CDS-header$$
2
3 #include <cds/memory/michael/allocator.h>
4 #include <iostream>
5
6 namespace memory {
7     namespace ma = cds::memory::michael;
8
9     typedef ma::Heap<
10         ma::opt::procheap_stat<ma::procheap_empty_stat>,
11         ma::opt::os_allocated_stat<ma::os_allocated_empty>,
12         ma::opt::check_bounds<ma::debug_bound_checking>
13     >      t_MichaelHeap_NoStat;
14
15     typedef ma::Heap<
16         ma::opt::procheap_stat<ma::procheap_atomic_stat >,
17         ma::opt::os_allocated_stat<ma::os_allocated_atomic >,
18         ma::opt::check_bounds<ma::debug_bound_checking>
19     >  t_MichaelHeap_Stat;
20
21     typedef ma::summary_stat            summary_stat;
22
23     extern t_MichaelHeap_NoStat  s_MichaelHeap_NoStat;
24     extern t_MichaelHeap_Stat    s_MichaelHeap_Stat;
25
26     template <typename T>
27     class MichaelHeap_NoStat
28     {
29     public:
30         typedef T value_type;
31         typedef T * pointer;
32
33         enum {
34             alignment = 1
35         };
36
37
38         pointer allocate( size_t nSize, const void * pHint )
39         {
40             return reinterpret_cast<pointer>( s_MichaelHeap_NoStat.alloc( sizeof(T) * nSize ) );
41         }
42
43         void deallocate( pointer p, size_t nCount )
44         {
45             s_MichaelHeap_NoStat.free( p );
46         }
47
48         static void stat(summary_stat& s)
49         {
50             s_MichaelHeap_NoStat.summaryStat(s);
51         }
52     };
53
54     template <typename T>
55     class std_allocator: public std::allocator<T>
56     {
57     public:
58         enum {
59             alignment = 1
60         };
61
62         static void stat(summary_stat& s)
63         {}
64     };
65
66     template <typename T>
67     class MichaelHeap_Stat
68     {
69     public:
70         typedef T value_type;
71         typedef T * pointer;
72
73         enum {
74             alignment = 1
75         };
76
77         pointer allocate( size_t nSize, const void * pHint )
78         {
79             return reinterpret_cast<pointer>( s_MichaelHeap_Stat.alloc( sizeof(T) * nSize ) );
80         }
81
82         void deallocate( pointer p, size_t nCount )
83         {
84             s_MichaelHeap_Stat.free( p );
85         }
86
87         static void stat(summary_stat& s)
88         {
89             s_MichaelHeap_Stat.summaryStat(s);
90         }
91     };
92
93     template <typename T, size_t ALIGN>
94     class MichaelAlignHeap_NoStat
95     {
96     public:
97         typedef T value_type;
98         typedef T * pointer;
99
100         enum {
101             alignment = ALIGN
102         };
103
104         pointer allocate( size_t nSize, const void * pHint )
105         {
106             return reinterpret_cast<pointer>( s_MichaelHeap_NoStat.alloc_aligned( sizeof(T) * nSize, ALIGN ) );
107         }
108
109         void deallocate( pointer p, size_t nCount )
110         {
111             s_MichaelHeap_NoStat.free_aligned( p );
112         }
113
114         static void stat(summary_stat& s)
115         {
116             s_MichaelHeap_NoStat.summaryStat(s);
117         }
118     };
119
120     template <typename T, size_t ALIGN>
121     class MichaelAlignHeap_Stat {
122     public:
123         typedef T value_type;
124         typedef T * pointer;
125
126         enum {
127             alignment = ALIGN
128         };
129
130         pointer allocate( size_t nSize, const void * pHint )
131         {
132             return reinterpret_cast<pointer>( s_MichaelHeap_Stat.alloc_aligned( sizeof(T) * nSize, ALIGN ) );
133         }
134
135         void deallocate( pointer p, size_t nCount )
136         {
137             s_MichaelHeap_Stat.free_aligned( p );
138         }
139
140         static void stat(summary_stat& s)
141         {
142             s_MichaelHeap_Stat.summaryStat(s);
143         }
144     };
145
146     template <typename T, size_t ALIGN>
147     class system_aligned_allocator
148     {
149     public:
150         typedef T value_type;
151         typedef T * pointer;
152
153         enum {
154             alignment = ALIGN
155         };
156
157         pointer allocate( size_t nSize, const void * pHint )
158         {
159             return reinterpret_cast<pointer>( cds::OS::aligned_malloc( sizeof(T) * nSize, ALIGN ) );
160         }
161
162         void deallocate( pointer p, size_t nCount )
163         {
164             cds::OS::aligned_free( p );
165         }
166
167         static void stat(summary_stat& s)
168         {}
169     };
170
171     static inline std::ostream& operator <<(std::ostream& os, const summary_stat& s)
172     {
173         os  << "\t         alloc from active: " << s.nAllocFromActive << "\n"
174             << "\t        alloc from partial: " << s.nAllocFromPartial << "\n"
175             << "\t            alloc from new: " << s.nAllocFromNew << "\n"
176             << "\t           free call count: " << s.nFreeCount << "\n"
177             << "\t      superblock allocated: " << s.nPageAllocCount << "\n"
178             << "\t    superblock deallocated: " << s.nPageDeallocCount << "\n"
179             << "\t superblock desc allocated: " << s.nDescAllocCount << "\n"
180             << "\t      superblock full desc: " << s.nDescFull << "\n"
181             << "\t     total allocated bytes: " << s.nBytesAllocated << "\n"
182             << "\t   total deallocated bytes: " << s.nBytesDeallocated << "\n"
183             << "\tOS-allocated large blocks\n"
184             << "\t          alloc call count: " << s.nSysAllocCount << "\n"
185             << "\t           free call count: " << s.nSysFreeCount << "\n"
186             << "\t     total allocated bytes: " << s.nSysBytesAllocated << "\n"
187             << "\t   total deallocated bytes: " << s.nSysBytesDeallocated << "\n"
188             << "\tCAS contention indicators\n"
189             << "\t updating active field of active block: " << s.nActiveDescCASFailureCount << "\n"
190             << "\t updating anchor field of active block: " << s.nActiveAnchorCASFailureCount << "\n"
191             << "\tupdating active field of partial block: " << s.nPartialDescCASFailureCount << "\n"
192             << "\tupdating anchor field of partial block: " << s.nPartialAnchorCASFailureCount
193             << std::endl;
194
195         return os;
196     }
197 }