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 #ifndef CDSLIB_MEMORY_MICHAEL_ALLOCATOR_PROCHEAP_STAT_H
32 #define CDSLIB_MEMORY_MICHAEL_ALLOCATOR_PROCHEAP_STAT_H
34 #include <cds/algo/atomic.h>
36 namespace cds { namespace memory { namespace michael {
38 /// processor heap statistics
40 This class is implementation of \ref opt::procheap_stat option.
41 The statistic counter implementation is based on atomic operations.
44 - \p INC_FENCE - memory fence for increment operation (default is release semantics)
45 - \p READ_FENCE - memory fence for reading of statistic values (default is acquire semantics)
47 class procheap_atomic_stat
50 atomics::atomic<size_t> nAllocFromActive ; ///< Event count of allocation from active superblock
51 atomics::atomic<size_t> nAllocFromPartial ; ///< Event count of allocation from partial superblock
52 atomics::atomic<size_t> nAllocFromNew ; ///< Event count of allocation from new superblock
53 atomics::atomic<size_t> nFreeCount ; ///< \ref free function call count
54 atomics::atomic<size_t> nBlockCount ; ///< Count of superblock allocated
55 atomics::atomic<size_t> nBlockDeallocCount ; ///< Count of superblock deallocated
56 atomics::atomic<size_t> nDescAllocCount ; ///< Count of superblock descriptors
57 atomics::atomic<size_t> nDescFull ; ///< Count of full superblock
58 atomics::atomic<unsigned long long> nBytesAllocated ; ///< Count of allocated bytes
59 atomics::atomic<unsigned long long> nBytesDeallocated ; ///< Count of deallocated bytes
61 atomics::atomic<size_t> nActiveDescCASFailureCount ; ///< CAS failure counter for active block of \p alloc_from_active Heap function
62 atomics::atomic<size_t> nActiveAnchorCASFailureCount; ///< CAS failure counter for active block of \p alloc_from_active Heap function
63 atomics::atomic<size_t> nPartialDescCASFailureCount ; ///< CAS failure counter for partial block of \p alloc_from_partial Heap function
64 atomics::atomic<size_t> nPartialAnchorCASFailureCount; ///< CAS failure counter for partial block of \p alloc_from_partial Heap function
70 procheap_atomic_stat()
72 , nAllocFromPartial(0)
78 , nBytesDeallocated(0)
79 , nActiveDescCASFailureCount(0)
80 , nActiveAnchorCASFailureCount(0)
81 , nPartialDescCASFailureCount(0)
82 , nPartialAnchorCASFailureCount(0)
87 /// Increment event counter of allocation from active superblock
88 void incAllocFromActive()
90 nAllocFromActive.fetch_add( 1, atomics::memory_order_relaxed );
92 /// Increment event counter of allocation from active superblock by \p n
93 void incAllocFromActive( size_t n )
95 nAllocFromActive.fetch_add( n, atomics::memory_order_relaxed );
98 /// Increment event counter of allocation from partial superblock
99 void incAllocFromPartial()
101 nAllocFromPartial.fetch_add( 1, atomics::memory_order_relaxed );
103 /// Increment event counter of allocation from partial superblock by \p n
104 void incAllocFromPartial( size_t n )
106 nAllocFromPartial.fetch_add( n, atomics::memory_order_relaxed );
109 /// Increment event count of allocation from new superblock
110 void incAllocFromNew()
112 nAllocFromNew.fetch_add( 1, atomics::memory_order_relaxed );
114 /// Increment event count of allocation from new superblock by \p n
115 void incAllocFromNew( size_t n )
117 nAllocFromNew.fetch_add( n, atomics::memory_order_relaxed );
120 /// Increment event counter of free calling
123 nFreeCount.fetch_add( 1, atomics::memory_order_relaxed );
125 /// Increment event counter of free calling by \p n
126 void incFreeCount( size_t n )
128 nFreeCount.fetch_add( n, atomics::memory_order_relaxed );
131 /// Increment counter of superblock allocated
132 void incBlockAllocated()
134 nBlockCount.fetch_add( 1, atomics::memory_order_relaxed );
136 /// Increment counter of superblock allocated by \p n
137 void incBlockAllocated( size_t n )
139 nBlockCount.fetch_add( n, atomics::memory_order_relaxed );
142 /// Increment counter of superblock deallocated
143 void incBlockDeallocated()
145 nBlockDeallocCount.fetch_add( 1, atomics::memory_order_relaxed );
147 /// Increment counter of superblock deallocated by \p n
148 void incBlockDeallocated( size_t n )
150 nBlockDeallocCount.fetch_add( n, atomics::memory_order_relaxed );
153 /// Increment counter of superblock descriptor allocated
154 void incDescAllocCount()
156 nDescAllocCount.fetch_add( 1, atomics::memory_order_relaxed );
158 /// Increment counter of superblock descriptor allocated by \p n
159 void incDescAllocCount( size_t n )
161 nDescAllocCount.fetch_add( n, atomics::memory_order_relaxed );
164 /// Increment counter of full superblock descriptor
167 nDescFull.fetch_add( 1, atomics::memory_order_relaxed );
169 /// Increment counter of full superblock descriptor by \p n
170 void incDescFull( size_t n )
172 nDescFull.fetch_add( n, atomics::memory_order_relaxed );
175 /// Decrement counter of full superblock descriptor
178 nDescFull.fetch_sub( 1, atomics::memory_order_relaxed );
180 /// Decrement counter of full superblock descriptor by \p n
181 void decDescFull(size_t n)
183 nDescFull.fetch_sub( n, atomics::memory_order_relaxed );
185 /// Add \p nBytes to allocated bytes counter
186 void incAllocatedBytes( size_t nBytes )
188 nBytesAllocated.fetch_add( nBytes, atomics::memory_order_relaxed );
190 /// Add \p nBytes to deallocated bytes counter
191 void incDeallocatedBytes( size_t nBytes )
193 nBytesDeallocated.fetch_add( nBytes, atomics::memory_order_relaxed);
196 /// Add \p nCount to CAS failure counter of updating \p active field of active descriptor for \p alloc_from_active internal Heap function
197 void incActiveDescCASFailureCount( int nCount )
199 nActiveDescCASFailureCount.fetch_add( nCount, atomics::memory_order_relaxed );
202 /// Add \p nCount to CAS failure counter of updating \p anchor field of active descriptor for \p alloc_from_active internal Heap function
203 void incActiveAnchorCASFailureCount( int nCount )
205 nActiveAnchorCASFailureCount.fetch_add( nCount, atomics::memory_order_relaxed );
208 /// Add \p nCount to CAS failure counter of updating \p active field of partial descriptor for \p alloc_from_partial internal Heap function
209 void incPartialDescCASFailureCount( int nCount )
211 nPartialDescCASFailureCount.fetch_add( nCount, atomics::memory_order_relaxed );
214 /// Add \p nCount to CAS failure counter of updating \p anchor field of partial descriptor for \p alloc_from_partial internal Heap function
215 void incPartialAnchorCASFailureCount( int nCount )
217 nPartialAnchorCASFailureCount.fetch_add( nCount, atomics::memory_order_relaxed );
220 // -----------------------------------------------------------------
223 /// Read event counter of allocation from active superblock
224 size_t allocFromActive() const
226 return nAllocFromActive.load(atomics::memory_order_relaxed);
229 /// Read event counter of allocation from partial superblock
230 size_t allocFromPartial() const
232 return nAllocFromPartial.load(atomics::memory_order_relaxed);
235 /// Read event count of allocation from new superblock
236 size_t allocFromNew() const
238 return nAllocFromNew.load(atomics::memory_order_relaxed);
241 /// Read event counter of free calling
242 size_t freeCount() const
244 return nFreeCount.load(atomics::memory_order_relaxed);
247 /// Read counter of superblock allocated
248 size_t blockAllocated() const
250 return nBlockCount.load(atomics::memory_order_relaxed);
253 /// Read counter of superblock deallocated
254 size_t blockDeallocated() const
256 return nBlockDeallocCount.load(atomics::memory_order_relaxed);
259 /// Read counter of superblock descriptor allocated
260 size_t descAllocCount() const
262 return nDescAllocCount.load(atomics::memory_order_relaxed);
265 /// Read counter of full superblock descriptor
266 size_t descFull() const
268 return nDescFull.load(atomics::memory_order_relaxed);
271 /// Get counter of allocated bytes
273 This counter only counts the bytes allocated by Heap, OS allocation (large blocks) is not counted.
275 To get count of bytes allocated but not yet deallocated you should call
276 \code allocatedBytes() - deallocatedBytes() \endcode
278 uint64_t allocatedBytes() const
280 return nBytesAllocated.load(atomics::memory_order_relaxed);
283 /// Get counter of deallocated bytes
285 This counter only counts the bytes allocated by Heap, OS allocation (large blocks) is not counted.unter of deallocated bytes
287 See \ref allocatedBytes notes
289 uint64_t deallocatedBytes() const
291 return nBytesDeallocated.load(atomics::memory_order_relaxed);
294 /// Get CAS failure counter of updating \p active field of active descriptor for \p alloc_from_active internal Heap function
295 size_t activeDescCASFailureCount() const
297 return nActiveDescCASFailureCount.load(atomics::memory_order_relaxed);
300 /// Get CAS failure counter of updating \p anchor field of active descriptor for \p alloc_from_active internal Heap function
301 size_t activeAnchorCASFailureCount() const
303 return nActiveAnchorCASFailureCount.load(atomics::memory_order_relaxed);
306 /// Get CAS failure counter of updating \p active field of partial descriptor for \p alloc_from_active internal Heap function
307 size_t partialDescCASFailureCount() const
309 return nPartialDescCASFailureCount.load(atomics::memory_order_relaxed);
312 /// Get CAS failure counter of updating \p anchor field of partial descriptor for \p alloc_from_active internal Heap function
313 size_t partialAnchorCASFailureCount() const
315 return nPartialAnchorCASFailureCount.load(atomics::memory_order_relaxed);
319 /// Empty processor heap statistics
321 This class is dummy implementation of \ref opt::procheap_stat option.
322 No statistic gathering is performed.
324 Interface - see procheap_atomic_stat.
325 All getter methods return 0.
327 class procheap_empty_stat
331 void incAllocFromActive()
333 void incAllocFromPartial()
335 void incAllocFromNew()
339 void incBlockAllocated()
341 void incBlockDeallocated()
343 void incDescAllocCount()
350 // Add -------------------------------------------------------------
351 void incAllocFromActive(size_t)
353 void incAllocFromPartial(size_t)
355 void incAllocFromNew(size_t)
357 void incFreeCount(size_t)
359 void incBlockAllocated(size_t)
361 void incBlockDeallocated(size_t)
363 void incDescAllocCount(size_t)
365 void incDescFull(size_t)
367 void decDescFull(size_t)
369 void incAllocatedBytes( size_t /*nBytes*/ )
371 void incDeallocatedBytes( size_t /*nBytes*/ )
373 void incActiveDescCASFailureCount( int /*nCount*/ )
375 void incActiveAnchorCASFailureCount( int /*nCount*/ )
377 void incPartialDescCASFailureCount( int /*nCount*/ )
379 void incPartialAnchorCASFailureCount( int /*nCount*/ )
382 // -----------------------------------------------------------------
385 size_t allocFromActive() const
387 size_t allocFromPartial() const
389 size_t allocFromNew() const
391 size_t freeCount() const
393 size_t blockAllocated() const
395 size_t blockDeallocated() const
397 size_t descAllocCount() const
399 size_t descFull() const
401 uint64_t allocatedBytes() const
403 uint64_t deallocatedBytes() const
405 size_t activeDescCASFailureCount() const
407 size_t activeAnchorCASFailureCount() const
409 size_t partialDescCASFailureCount() const
411 size_t partialAnchorCASFailureCount() const
418 }}} // namespace cds::memory::michael
420 #endif /// CDSLIB_MEMORY_MICHAEL_ALLOCATOR_PROCHEAP_STAT_H