3 #ifndef CDSLIB_MEMORY_MICHAEL_ALLOCATOR_PROCHEAP_STAT_H
4 #define CDSLIB_MEMORY_MICHAEL_ALLOCATOR_PROCHEAP_STAT_H
6 #include <cds/algo/atomic.h>
8 namespace cds { namespace memory { namespace michael {
10 /// processor heap statistics
12 This class is implementation of \ref opt::procheap_stat option.
13 The statistic counter implementation is based on atomic operations.
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)
19 class procheap_atomic_stat
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
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
42 procheap_atomic_stat()
44 , nAllocFromPartial(0)
50 , nBytesDeallocated(0)
51 , nActiveDescCASFailureCount(0)
52 , nActiveAnchorCASFailureCount(0)
53 , nPartialDescCASFailureCount(0)
54 , nPartialAnchorCASFailureCount(0)
59 /// Increment event counter of allocation from active superblock
60 void incAllocFromActive()
62 nAllocFromActive.fetch_add( 1, atomics::memory_order_relaxed );
64 /// Increment event counter of allocation from active superblock by \p n
65 void incAllocFromActive( size_t n )
67 nAllocFromActive.fetch_add( n, atomics::memory_order_relaxed );
70 /// Increment event counter of allocation from partial superblock
71 void incAllocFromPartial()
73 nAllocFromPartial.fetch_add( 1, atomics::memory_order_relaxed );
75 /// Increment event counter of allocation from partial superblock by \p n
76 void incAllocFromPartial( size_t n )
78 nAllocFromPartial.fetch_add( n, atomics::memory_order_relaxed );
81 /// Increment event count of allocation from new superblock
82 void incAllocFromNew()
84 nAllocFromNew.fetch_add( 1, atomics::memory_order_relaxed );
86 /// Increment event count of allocation from new superblock by \p n
87 void incAllocFromNew( size_t n )
89 nAllocFromNew.fetch_add( n, atomics::memory_order_relaxed );
92 /// Increment event counter of free calling
95 nFreeCount.fetch_add( 1, atomics::memory_order_relaxed );
97 /// Increment event counter of free calling by \p n
98 void incFreeCount( size_t n )
100 nFreeCount.fetch_add( n, atomics::memory_order_relaxed );
103 /// Increment counter of superblock allocated
104 void incBlockAllocated()
106 nBlockCount.fetch_add( 1, atomics::memory_order_relaxed );
108 /// Increment counter of superblock allocated by \p n
109 void incBlockAllocated( size_t n )
111 nBlockCount.fetch_add( n, atomics::memory_order_relaxed );
114 /// Increment counter of superblock deallocated
115 void incBlockDeallocated()
117 nBlockDeallocCount.fetch_add( 1, atomics::memory_order_relaxed );
119 /// Increment counter of superblock deallocated by \p n
120 void incBlockDeallocated( size_t n )
122 nBlockDeallocCount.fetch_add( n, atomics::memory_order_relaxed );
125 /// Increment counter of superblock descriptor allocated
126 void incDescAllocCount()
128 nDescAllocCount.fetch_add( 1, atomics::memory_order_relaxed );
130 /// Increment counter of superblock descriptor allocated by \p n
131 void incDescAllocCount( size_t n )
133 nDescAllocCount.fetch_add( n, atomics::memory_order_relaxed );
136 /// Increment counter of full superblock descriptor
139 nDescFull.fetch_add( 1, atomics::memory_order_relaxed );
141 /// Increment counter of full superblock descriptor by \p n
142 void incDescFull( size_t n )
144 nDescFull.fetch_add( n, atomics::memory_order_relaxed );
147 /// Decrement counter of full superblock descriptor
150 nDescFull.fetch_sub( 1, atomics::memory_order_relaxed );
152 /// Decrement counter of full superblock descriptor by \p n
153 void decDescFull(size_t n)
155 nDescFull.fetch_sub( n, atomics::memory_order_relaxed );
157 /// Add \p nBytes to allocated bytes counter
158 void incAllocatedBytes( size_t nBytes )
160 nBytesAllocated.fetch_add( nBytes, atomics::memory_order_relaxed );
162 /// Add \p nBytes to deallocated bytes counter
163 void incDeallocatedBytes( size_t nBytes )
165 nBytesDeallocated.fetch_add( nBytes, atomics::memory_order_relaxed);
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 )
171 nActiveDescCASFailureCount.fetch_add( nCount, atomics::memory_order_relaxed );
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 )
177 nActiveAnchorCASFailureCount.fetch_add( nCount, atomics::memory_order_relaxed );
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 )
183 nPartialDescCASFailureCount.fetch_add( nCount, atomics::memory_order_relaxed );
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 )
189 nPartialAnchorCASFailureCount.fetch_add( nCount, atomics::memory_order_relaxed );
192 // -----------------------------------------------------------------
195 /// Read event counter of allocation from active superblock
196 size_t allocFromActive() const
198 return nAllocFromActive.load(atomics::memory_order_relaxed);
201 /// Read event counter of allocation from partial superblock
202 size_t allocFromPartial() const
204 return nAllocFromPartial.load(atomics::memory_order_relaxed);
207 /// Read event count of allocation from new superblock
208 size_t allocFromNew() const
210 return nAllocFromNew.load(atomics::memory_order_relaxed);
213 /// Read event counter of free calling
214 size_t freeCount() const
216 return nFreeCount.load(atomics::memory_order_relaxed);
219 /// Read counter of superblock allocated
220 size_t blockAllocated() const
222 return nBlockCount.load(atomics::memory_order_relaxed);
225 /// Read counter of superblock deallocated
226 size_t blockDeallocated() const
228 return nBlockDeallocCount.load(atomics::memory_order_relaxed);
231 /// Read counter of superblock descriptor allocated
232 size_t descAllocCount() const
234 return nDescAllocCount.load(atomics::memory_order_relaxed);
237 /// Read counter of full superblock descriptor
238 size_t descFull() const
240 return nDescFull.load(atomics::memory_order_relaxed);
243 /// Get counter of allocated bytes
245 This counter only counts the bytes allocated by Heap, OS allocation (large blocks) is not counted.
247 To get count of bytes allocated but not yet deallocated you should call
248 \code allocatedBytes() - deallocatedBytes() \endcode
250 atomic64u_t allocatedBytes() const
252 return nBytesAllocated.load(atomics::memory_order_relaxed);
255 /// Get counter of deallocated bytes
257 This counter only counts the bytes allocated by Heap, OS allocation (large blocks) is not counted.unter of deallocated bytes
259 See \ref allocatedBytes notes
261 atomic64u_t deallocatedBytes() const
263 return nBytesDeallocated.load(atomics::memory_order_relaxed);
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
269 return nActiveDescCASFailureCount.load(atomics::memory_order_relaxed);
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
275 return nActiveAnchorCASFailureCount.load(atomics::memory_order_relaxed);
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
281 return nPartialDescCASFailureCount.load(atomics::memory_order_relaxed);
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
287 return nPartialAnchorCASFailureCount.load(atomics::memory_order_relaxed);
291 /// Empty processor heap statistics
293 This class is dummy implementation of \ref opt::procheap_stat option.
294 No statistic gathering is performed.
296 Interface - see procheap_atomic_stat.
297 All getter methods return 0.
299 class procheap_empty_stat
303 void incAllocFromActive()
305 void incAllocFromPartial()
307 void incAllocFromNew()
311 void incBlockAllocated()
313 void incBlockDeallocated()
315 void incDescAllocCount()
322 // Add -------------------------------------------------------------
323 void incAllocFromActive(size_t)
325 void incAllocFromPartial(size_t)
327 void incAllocFromNew(size_t)
329 void incFreeCount(size_t)
331 void incBlockAllocated(size_t)
333 void incBlockDeallocated(size_t)
335 void incDescAllocCount(size_t)
337 void incDescFull(size_t)
339 void decDescFull(size_t)
341 void incAllocatedBytes( size_t /*nBytes*/ )
343 void incDeallocatedBytes( size_t /*nBytes*/ )
345 void incActiveDescCASFailureCount( int /*nCount*/ )
347 void incActiveAnchorCASFailureCount( int /*nCount*/ )
349 void incPartialDescCASFailureCount( int /*nCount*/ )
351 void incPartialAnchorCASFailureCount( int /*nCount*/ )
354 // -----------------------------------------------------------------
357 size_t allocFromActive() const
359 size_t allocFromPartial() const
361 size_t allocFromNew() const
363 size_t freeCount() const
365 size_t blockAllocated() const
367 size_t blockDeallocated() const
369 size_t descAllocCount() const
371 size_t descFull() const
373 atomic64u_t allocatedBytes() const
375 atomic64u_t deallocatedBytes() const
377 size_t activeDescCASFailureCount() const
379 size_t activeAnchorCASFailureCount() const
381 size_t partialDescCASFailureCount() const
383 size_t partialAnchorCASFailureCount() const
390 }}} // namespace cds::memory::michael
392 #endif /// CDSLIB_MEMORY_MICHAEL_ALLOCATOR_PROCHEAP_STAT_H