issue#11: cds: changed __CDS_ guard prefix to CDSLIB_ for all .h files
[libcds.git] / cds / memory / michael / procheap_stat.h
1 //$$CDS-header$$
2
3 #ifndef CDSLIB_MEMORY_MICHAEL_ALLOCATOR_PROCHEAP_STAT_H
4 #define CDSLIB_MEMORY_MICHAEL_ALLOCATOR_PROCHEAP_STAT_H
5
6 #include <cds/algo/atomic.h>
7
8 namespace cds { namespace memory { namespace michael {
9
10         /// processor heap statistics
11     /**
12         This class is implementation of \ref opt::procheap_stat option.
13         The statistic counter implementation is based on atomic operations.
14
15         Template parameters:
16             - \p INC_FENCE - memory fence for increment operation (default is release semantics)
17             - \p READ_FENCE - memory fence for reading of statistic values (default is acquire semantics)
18     */
19     class procheap_atomic_stat
20     {
21         //@cond
22         atomics::atomic<size_t>      nAllocFromActive    ;  ///< Event count of allocation from active superblock
23         atomics::atomic<size_t>      nAllocFromPartial   ;  ///< Event count of allocation from partial superblock
24         atomics::atomic<size_t>      nAllocFromNew       ;  ///< Event count of allocation from new superblock
25         atomics::atomic<size_t>      nFreeCount          ;  ///< \ref free function call count
26         atomics::atomic<size_t>      nBlockCount         ;  ///< Count of superblock allocated
27         atomics::atomic<size_t>      nBlockDeallocCount  ;  ///< Count of superblock deallocated
28         atomics::atomic<size_t>      nDescAllocCount     ;  ///< Count of superblock descriptors
29         atomics::atomic<size_t>      nDescFull           ;  ///< Count of full superblock
30         atomics::atomic<unsigned long long> nBytesAllocated     ;  ///< Count of allocated bytes
31         atomics::atomic<unsigned long long> nBytesDeallocated   ;  ///< Count of deallocated bytes
32
33         atomics::atomic<size_t>      nActiveDescCASFailureCount ;   ///< CAS failure counter for active block of \p alloc_from_active Heap function
34         atomics::atomic<size_t>      nActiveAnchorCASFailureCount;   ///< CAS failure counter for active block of \p alloc_from_active Heap function
35         atomics::atomic<size_t>      nPartialDescCASFailureCount ;   ///< CAS failure counter for partial block of \p alloc_from_partial Heap function
36         atomics::atomic<size_t>      nPartialAnchorCASFailureCount;   ///< CAS failure counter for partial block of \p alloc_from_partial Heap function
37
38         //@endcond
39
40     public:
41         //@cond
42         procheap_atomic_stat()
43             : nAllocFromActive(0)
44             , nAllocFromPartial(0)
45             , nAllocFromNew(0)
46             , nFreeCount(0)
47             , nBlockCount(0)
48             , nDescFull(0)
49             , nBytesAllocated(0)
50             , nBytesDeallocated(0)
51             , nActiveDescCASFailureCount(0)
52             , nActiveAnchorCASFailureCount(0)
53             , nPartialDescCASFailureCount(0)
54             , nPartialAnchorCASFailureCount(0)
55         {}
56         //@endcond
57
58     public:
59         /// Increment event counter of allocation from active superblock
60         void incAllocFromActive()
61         {
62             nAllocFromActive.fetch_add( 1, atomics::memory_order_relaxed );
63         }
64         /// Increment event counter of allocation from active superblock by \p n
65         void incAllocFromActive( size_t n )
66         {
67             nAllocFromActive.fetch_add( n, atomics::memory_order_relaxed );
68         }
69
70         /// Increment event counter of allocation from partial superblock
71         void incAllocFromPartial()
72         {
73             nAllocFromPartial.fetch_add( 1, atomics::memory_order_relaxed );
74         }
75         /// Increment event counter of allocation from partial superblock by \p n
76         void incAllocFromPartial( size_t n )
77         {
78             nAllocFromPartial.fetch_add( n, atomics::memory_order_relaxed );
79         }
80
81         /// Increment event count of allocation from new superblock
82         void incAllocFromNew()
83         {
84             nAllocFromNew.fetch_add( 1, atomics::memory_order_relaxed );
85         }
86         /// Increment event count of allocation from new superblock by \p n
87         void incAllocFromNew( size_t n )
88         {
89             nAllocFromNew.fetch_add( n, atomics::memory_order_relaxed );
90         }
91
92         /// Increment event counter of free calling
93         void incFreeCount()
94         {
95             nFreeCount.fetch_add( 1, atomics::memory_order_relaxed );
96         }
97         /// Increment event counter of free calling by \p n
98         void incFreeCount( size_t n )
99         {
100             nFreeCount.fetch_add( n, atomics::memory_order_relaxed );
101         }
102
103         /// Increment counter of superblock allocated
104         void incBlockAllocated()
105         {
106             nBlockCount.fetch_add( 1, atomics::memory_order_relaxed );
107         }
108         /// Increment counter of superblock allocated by \p n
109         void incBlockAllocated( size_t n )
110         {
111             nBlockCount.fetch_add( n, atomics::memory_order_relaxed );
112         }
113
114         /// Increment counter of superblock deallocated
115         void incBlockDeallocated()
116         {
117             nBlockDeallocCount.fetch_add( 1, atomics::memory_order_relaxed );
118         }
119         /// Increment counter of superblock deallocated by \p n
120         void incBlockDeallocated( size_t n )
121         {
122             nBlockDeallocCount.fetch_add( n, atomics::memory_order_relaxed );
123         }
124
125         /// Increment counter of superblock descriptor allocated
126         void incDescAllocCount()
127         {
128             nDescAllocCount.fetch_add( 1, atomics::memory_order_relaxed );
129         }
130         /// Increment counter of superblock descriptor allocated by \p n
131         void incDescAllocCount( size_t n )
132         {
133             nDescAllocCount.fetch_add( n, atomics::memory_order_relaxed );
134         }
135
136         /// Increment counter of full superblock descriptor
137         void incDescFull()
138         {
139             nDescFull.fetch_add( 1, atomics::memory_order_relaxed );
140         }
141         /// Increment counter of full superblock descriptor by \p n
142         void incDescFull( size_t n )
143         {
144             nDescFull.fetch_add( n, atomics::memory_order_relaxed );
145         }
146
147         /// Decrement counter of full superblock descriptor
148         void decDescFull()
149         {
150             nDescFull.fetch_sub( 1, atomics::memory_order_relaxed );
151         }
152         /// Decrement counter of full superblock descriptor by \p n
153         void decDescFull(size_t n)
154         {
155             nDescFull.fetch_sub( n, atomics::memory_order_relaxed );
156         }
157         /// Add \p nBytes to allocated bytes counter
158         void incAllocatedBytes( size_t nBytes )
159         {
160             nBytesAllocated.fetch_add( nBytes, atomics::memory_order_relaxed );
161         }
162         /// Add \p nBytes to deallocated bytes counter
163         void incDeallocatedBytes( size_t nBytes )
164         {
165             nBytesDeallocated.fetch_add( nBytes, atomics::memory_order_relaxed);
166         }
167
168         /// Add \p nCount to CAS failure counter of updating \p active field of active descriptor for \p alloc_from_active internal Heap function
169         void incActiveDescCASFailureCount( int nCount )
170         {
171             nActiveDescCASFailureCount.fetch_add( nCount, atomics::memory_order_relaxed );
172         }
173
174         /// Add \p nCount to CAS failure counter of updating \p anchor field of active descriptor for \p alloc_from_active internal Heap function
175         void incActiveAnchorCASFailureCount( int nCount )
176         {
177             nActiveAnchorCASFailureCount.fetch_add( nCount, atomics::memory_order_relaxed );
178         }
179
180         /// Add \p nCount to CAS failure counter of updating \p active field of partial descriptor for \p alloc_from_partial internal Heap function
181         void incPartialDescCASFailureCount( int nCount )
182         {
183             nPartialDescCASFailureCount.fetch_add( nCount, atomics::memory_order_relaxed );
184         }
185
186         /// Add \p nCount to CAS failure counter of updating \p anchor field of partial descriptor for \p alloc_from_partial internal Heap function
187         void incPartialAnchorCASFailureCount( int nCount )
188         {
189             nPartialAnchorCASFailureCount.fetch_add( nCount, atomics::memory_order_relaxed );
190         }
191
192         // -----------------------------------------------------------------
193         // Reading
194
195         /// Read event counter of allocation from active superblock
196         size_t allocFromActive() const
197         {
198             return nAllocFromActive.load(atomics::memory_order_relaxed);
199         }
200
201         /// Read event counter of allocation from partial superblock
202         size_t allocFromPartial() const
203         {
204             return nAllocFromPartial.load(atomics::memory_order_relaxed);
205         }
206
207         /// Read event count of allocation from new superblock
208         size_t allocFromNew() const
209         {
210             return nAllocFromNew.load(atomics::memory_order_relaxed);
211         }
212
213         /// Read event counter of free calling
214         size_t freeCount() const
215         {
216             return nFreeCount.load(atomics::memory_order_relaxed);
217         }
218
219         /// Read counter of superblock allocated
220         size_t blockAllocated() const
221         {
222             return nBlockCount.load(atomics::memory_order_relaxed);
223         }
224
225         /// Read counter of superblock deallocated
226         size_t blockDeallocated() const
227         {
228             return nBlockDeallocCount.load(atomics::memory_order_relaxed);
229         }
230
231         /// Read counter of superblock descriptor allocated
232         size_t descAllocCount() const
233         {
234             return nDescAllocCount.load(atomics::memory_order_relaxed);
235         }
236
237         /// Read counter of full superblock descriptor
238         size_t descFull() const
239         {
240             return nDescFull.load(atomics::memory_order_relaxed);
241         }
242
243         /// Get counter of allocated bytes
244         /**
245             This counter only counts the bytes allocated by Heap, OS allocation (large blocks) is not counted.
246
247             To get count of bytes allocated but not yet deallocated you should call
248             \code allocatedBytes() - deallocatedBytes() \endcode
249         */
250         atomic64u_t allocatedBytes() const
251         {
252             return nBytesAllocated.load(atomics::memory_order_relaxed);
253         }
254
255         /// Get counter of deallocated bytes
256         /**
257             This counter only counts the bytes allocated by Heap, OS allocation (large blocks) is not counted.unter of deallocated bytes
258
259             See \ref allocatedBytes notes
260         */
261         atomic64u_t deallocatedBytes() const
262         {
263             return nBytesDeallocated.load(atomics::memory_order_relaxed);
264         }
265
266         /// Get CAS failure counter of updating \p active field of active descriptor for \p alloc_from_active internal Heap function
267         size_t activeDescCASFailureCount() const
268         {
269             return nActiveDescCASFailureCount.load(atomics::memory_order_relaxed);
270         }
271
272         /// Get CAS failure counter of updating \p anchor field of active descriptor for \p alloc_from_active internal Heap function
273         size_t activeAnchorCASFailureCount() const
274         {
275             return nActiveAnchorCASFailureCount.load(atomics::memory_order_relaxed);
276         }
277
278         /// Get CAS failure counter of updating \p active field of partial descriptor for \p alloc_from_active internal Heap function
279         size_t partialDescCASFailureCount() const
280         {
281             return nPartialDescCASFailureCount.load(atomics::memory_order_relaxed);
282         }
283
284         /// Get CAS failure counter of updating \p anchor field of partial descriptor for \p alloc_from_active internal Heap function
285         size_t partialAnchorCASFailureCount() const
286         {
287             return nPartialAnchorCASFailureCount.load(atomics::memory_order_relaxed);
288         }
289     };
290
291     /// Empty processor heap statistics
292     /**
293         This class is dummy implementation of \ref opt::procheap_stat option.
294         No statistic gathering is performed.
295
296         Interface - see procheap_atomic_stat.
297         All getter methods return 0.
298     */
299     class procheap_empty_stat
300     {
301     //@cond
302     public:
303         void incAllocFromActive()
304         {}
305         void incAllocFromPartial()
306         {}
307         void incAllocFromNew()
308         {}
309         void incFreeCount()
310         {}
311         void incBlockAllocated()
312         {}
313         void incBlockDeallocated()
314         {}
315         void incDescAllocCount()
316         {}
317         void incDescFull()
318         {}
319         void decDescFull()
320         {}
321
322         // Add -------------------------------------------------------------
323         void incAllocFromActive(size_t)
324         {}
325         void incAllocFromPartial(size_t)
326         {}
327         void incAllocFromNew(size_t)
328         {}
329         void incFreeCount(size_t)
330         {}
331         void incBlockAllocated(size_t)
332         {}
333         void incBlockDeallocated(size_t)
334         {}
335         void incDescAllocCount(size_t)
336         {}
337         void incDescFull(size_t)
338         {}
339         void decDescFull(size_t)
340         {}
341         void incAllocatedBytes( size_t /*nBytes*/ )
342         {}
343         void incDeallocatedBytes( size_t /*nBytes*/ )
344         {}
345         void incActiveDescCASFailureCount( int /*nCount*/ )
346         {}
347         void incActiveAnchorCASFailureCount( int /*nCount*/ )
348         {}
349         void incPartialDescCASFailureCount( int /*nCount*/ )
350         {}
351         void incPartialAnchorCASFailureCount( int /*nCount*/ )
352         {}
353
354         // -----------------------------------------------------------------
355         // Reading
356
357         size_t allocFromActive() const
358         { return 0; }
359         size_t allocFromPartial() const
360         { return 0; }
361         size_t allocFromNew() const
362         { return 0; }
363         size_t freeCount() const
364         { return 0; }
365         size_t blockAllocated() const
366         { return 0; }
367         size_t blockDeallocated() const
368         { return 0; }
369         size_t descAllocCount() const
370         { return 0; }
371         size_t descFull() const
372         { return 0; }
373         atomic64u_t allocatedBytes() const
374         { return 0; }
375         atomic64u_t deallocatedBytes() const
376         { return 0; }
377         size_t activeDescCASFailureCount() const
378         { return 0; }
379         size_t activeAnchorCASFailureCount() const
380         { return 0; }
381         size_t partialDescCASFailureCount() const
382         { return 0; }
383         size_t partialAnchorCASFailureCount() const
384         { return 0; }
385
386     //@endcond
387     };
388
389
390 }}} // namespace cds::memory::michael
391
392 #endif  /// CDSLIB_MEMORY_MICHAEL_ALLOCATOR_PROCHEAP_STAT_H