BDE 4.14.0 Production release
Loading...
Searching...
No Matches
ball_countingallocator.h
Go to the documentation of this file.
1/// @file ball_countingallocator.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// ball_countingallocator.h -*-C++-*-
8#ifndef INCLUDED_BALL_COUNTINGALLOCATOR
9#define INCLUDED_BALL_COUNTINGALLOCATOR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup ball_countingallocator ball_countingallocator
15/// @brief Provide a concrete allocator that keeps count of allocated bytes.
16/// @addtogroup bal
17/// @{
18/// @addtogroup ball
19/// @{
20/// @addtogroup ball_countingallocator
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#ball_countingallocator-purpose"> Purpose</a>
25/// * <a href="#ball_countingallocator-classes"> Classes </a>
26/// * <a href="#ball_countingallocator-description"> Description </a>
27/// * <a href="#ball_countingallocator-byte-count"> Byte Count </a>
28/// * <a href="#ball_countingallocator-usage"> Usage </a>
29/// * <a href="#ball_countingallocator-example-1-basic-usage"> Example 1: Basic Usage </a>
30///
31/// # Purpose {#ball_countingallocator-purpose}
32/// Provide a concrete allocator that keeps count of allocated bytes.
33///
34/// # Classes {#ball_countingallocator-classes}
35///
36/// - ball::CountingAllocator: maximally-aligning, instrumented allocator adaptor
37///
38/// @see ball_fixedsizerecordbuffer
39///
40/// # Description {#ball_countingallocator-description}
41/// This component provides a special-purpose instrumented
42/// allocator, `ball::CountingAllocator`, that implements the `bslma::Allocator`
43/// protocol and guarantees maximal alignment of allocated blocks, even when
44/// the allocator supplied at construction guarantees only natural alignment
45/// (or no alignment at all). `ball::CountingAllocator` maintains a
46/// user-resettable running sum of the total number of bytes
47/// allocated (called byte count, see below).
48/// @code
49/// ,-----------------------.
50/// ( ball::CountingAllocator )
51/// `-----------------------'
52/// | ctor/dtor
53/// | numBytesTotal
54/// | resetNumBytesTotal
55/// V
56/// ,----------------.
57/// ( bslma::Allocator )
58/// `----------------'
59/// allocate
60/// deallocate
61/// @endcode
62///
63/// ## Byte Count {#ball_countingallocator-byte-count}
64///
65///
66/// The byte count maintained by `ball::CountingAllocator` is set to 0 upon
67/// construction and after each call to `resetNumBytesTotal`. Each call of
68/// `allocate(size)` increases the byte count by the sum of the least
69/// multiple of `bsls::AlignmentUtil::BSLS_MAX_ALIGNMENT` that is greater than
70/// or equal to `size` and `bsls::AlignmentUtil::BSLS_MAX_ALIGNMENT`. Each call
71/// of `deallocate` decrements the byte count by the same amount by which the
72/// byte count was incremented on matching `allocate` call. The current
73/// value of the byte count is returned by the `numBytesTotal` accessor.
74///
75/// ## Usage {#ball_countingallocator-usage}
76///
77///
78/// This section illustrates intended use of this component.
79///
80/// ### Example 1: Basic Usage {#ball_countingallocator-example-1-basic-usage}
81///
82///
83/// In the following example we demonstrate how the counting allocator can be
84/// used to know the amount of dynamic memory allocated by a `vector<int>` after
85/// pushing one integer. Let us assume that memory for the vector comes from a
86/// `bslma::Allocator` named `allocator`.
87/// @code
88/// // First create the counting allocator using 'allocator'.
89/// BloombergLP::ball::CountingAllocator countingAllocator(allocator);
90///
91/// // Now create the vector using the counting allocator.
92/// bsl::vector<int> vec(&countingAllocator);
93///
94/// vec.push_back(1);
95/// // The following will print the memory consumed by the
96/// // vector and the counting allocator.
97/// bsl::cout << "dynamic memory after first push back: "
98/// << countingAllocator.numBytesTotal() << bsl::endl;
99/// @endcode
100/// @}
101/** @} */
102/** @} */
103
104/** @addtogroup bal
105 * @{
106 */
107/** @addtogroup ball
108 * @{
109 */
110/** @addtogroup ball_countingallocator
111 * @{
112 */
113
114#include <balscm_version.h>
115
116#include <bslma_allocator.h>
117#include <bslma_default.h>
118
119#include <bsls_alignmentutil.h>
120#include <bsls_keyword.h>
121
122
123namespace ball {
124
125 // =======================
126 // class CountingAllocator
127 // =======================
128
129/// This class maintains a count of the total number of allocated bytes.
130/// The running byte count is initialized to 0 upon construction, is
131/// increased by the `allocate` method, and may be reset to 0 by the
132/// `resetNumBytesTotal` method. The `deallocate` method appropriately
133/// decrement the byte count. The precise definition of byte count is
134/// described in the "Byte Count" section of the component-level
135/// documentation.
136///
137/// See @ref ball_countingallocator
139
140 // DATA
141 size_type d_byteCount; // byte count
142 bslma::Allocator *d_allocator_p; // holds (but does not own) allocator
143
144 private:
145 // NOT IMPLEMENTED
147 CountingAllocator& operator=(const CountingAllocator&);
148
149 public:
150 // CREATORS
151
152 /// Create a counting allocator having an initial byte count of 0.
153 /// Optionally specify a `basicAllocator` used to supply memory. If
154 /// `basicAllocator` is 0, the currently installed default allocator is
155 /// used.
156 explicit
157 CountingAllocator(bslma::Allocator *basicAllocator = 0);
158
159 /// Destroy this counting allocator.
161
162 // MANIPULATORS
163
164 /// Return a newly allocated block of memory of (at least) the specified
165 /// positive `size` (bytes) and increment the byte count maintained by
166 /// this counting allocator by the sum of the least multiple of
167 /// `bsls::AlignmentUtil::BSLS_MAX_ALIGNMENT` that is greater than or
168 /// equal to `size` and `bsls::AlignmentUtil::BSLS_MAX_ALIGNMENT`. The
169 /// behavior is undefined unless `0 <= size`. Note that the alignment
170 /// of the address returned is the maximum alignment for any fundamental
171 /// type defined for the calling platform, even if the supplied
172 /// allocator guarantees only natural alignment.
174
175 /// Return the memory at the specified `address` back to this allocator
176 /// and update the byte count maintained by this counting allocator
177 /// appropriately. If `address` is 0, this function has no effect. The
178 /// behavior is undefined unless `address` was allocated using this
179 /// allocator and has not already been deallocated.
180 void deallocate(void *address) BSLS_KEYWORD_OVERRIDE;
181
182 /// Reset the byte count maintained by this counting allocator to 0.
183 void resetNumBytesTotal();
184
185 // ACCESSORS
186
187 /// Return the byte count maintained by this counting allocator. The
188 /// precise definition of byte count is described in the "Byte Count"
189 /// section of the component-level documentation.
190 size_type numBytesTotal() const;
191};
192
193// ============================================================================
194// INLINE DEFINITIONS
195// ============================================================================
196
197 // -----------------------
198 // class CountingAllocator
199 // -----------------------
200
201// CREATORS
202inline
203CountingAllocator::CountingAllocator(bslma::Allocator *basicAllocator)
204: d_byteCount(0)
205, d_allocator_p(bslma::Default::allocator(basicAllocator))
206{
207}
208
209// MANIPULATORS
210inline
212{
213 size_type paddedSize =
215 size_type totalSize = paddedSize + bsls::AlignmentUtil::BSLS_MAX_ALIGNMENT;
216
217 d_byteCount += totalSize;
218 void *address = d_allocator_p->allocate(totalSize);
219 *((int *)address) = static_cast<int>(totalSize);
220 return (char *)address + bsls::AlignmentUtil::BSLS_MAX_ALIGNMENT;
221}
222
223inline
225{
226 if (address) {
227 address = (char *)address - bsls::AlignmentUtil::BSLS_MAX_ALIGNMENT;
228 d_byteCount -= *((int *)address);
229 d_allocator_p->deallocate(address);
230 }
231}
232
233inline
235{
236 d_byteCount = 0;
237}
238
239// ACCESSORS
240inline
242{
243 return d_byteCount;
244}
245
246} // close package namespace
247
248
249#endif
250
251// ----------------------------------------------------------------------------
252// Copyright 2015 Bloomberg Finance L.P.
253//
254// Licensed under the Apache License, Version 2.0 (the "License");
255// you may not use this file except in compliance with the License.
256// You may obtain a copy of the License at
257//
258// http://www.apache.org/licenses/LICENSE-2.0
259//
260// Unless required by applicable law or agreed to in writing, software
261// distributed under the License is distributed on an "AS IS" BASIS,
262// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
263// See the License for the specific language governing permissions and
264// limitations under the License.
265// ----------------------------- END-OF-FILE ----------------------------------
266
267/** @} */
268/** @} */
269/** @} */
Definition ball_countingallocator.h:138
void * allocate(size_type size) BSLS_KEYWORD_OVERRIDE
Definition ball_countingallocator.h:211
~CountingAllocator() BSLS_KEYWORD_OVERRIDE
Destroy this counting allocator.
void deallocate(void *address) BSLS_KEYWORD_OVERRIDE
Definition ball_countingallocator.h:224
size_type numBytesTotal() const
Definition ball_countingallocator.h:241
void resetNumBytesTotal()
Reset the byte count maintained by this counting allocator to 0.
Definition ball_countingallocator.h:234
Definition bslma_allocator.h:457
virtual void deallocate(void *address)=0
std::size_t size_type
Definition bslma_allocator.h:499
virtual void * allocate(size_type size)=0
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:653
Definition ball_administration.h:214
Definition balxml_encoderoptions.h:68
static std::size_t roundUpToMaximalAlignment(std::size_t size)
Definition bsls_alignmentutil.h:452
@ BSLS_MAX_ALIGNMENT
Definition bsls_alignmentutil.h:275