BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlma_blocklist.h
Go to the documentation of this file.
1/// @file bdlma_blocklist.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlma_blocklist.h -*-C++-*-
8#ifndef INCLUDED_BDLMA_BLOCKLIST
9#define INCLUDED_BDLMA_BLOCKLIST
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlma_blocklist bdlma_blocklist
15/// @brief Provide allocation and management of a sequence of memory blocks.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlma
19/// @{
20/// @addtogroup bdlma_blocklist
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlma_blocklist-purpose"> Purpose</a>
25/// * <a href="#bdlma_blocklist-classes"> Classes </a>
26/// * <a href="#bdlma_blocklist-description"> Description </a>
27/// * <a href="#bdlma_blocklist-usage"> Usage </a>
28/// * <a href="#bdlma_blocklist-example-1-using-a-bdlma-blocklist-in-a-memory-pool"> Example 1: Using a bdlma::BlockList in a Memory Pool </a>
29///
30/// # Purpose {#bdlma_blocklist-purpose}
31/// Provide allocation and management of a sequence of memory blocks.
32///
33/// # Classes {#bdlma_blocklist-classes}
34///
35/// - bdlma::BlockList: memory manager that allocates and manages memory blocks
36///
37/// @see bdlma_infrequentdeleteblocklist
38///
39/// # Description {#bdlma_blocklist-description}
40/// This component implements a low-level memory manager,
41/// `bdlma::BlockList`, that allocates and manages a sequence of memory blocks,
42/// each of a potentially different size as specified during the `allocate`
43/// method's invocation. The `release` method of a `bdlma::BlockList` object
44/// deallocates the entire sequence of outstanding memory blocks, as does its
45/// destructor. Note that a `bdlma::BlockList`, at a minor memory expense,
46/// allows for individual items to be deallocated.
47///
48/// ## Usage {#bdlma_blocklist-usage}
49///
50///
51/// This section illustrates intended use of this component.
52///
53/// ### Example 1: Using a bdlma::BlockList in a Memory Pool {#bdlma_blocklist-example-1-using-a-bdlma-blocklist-in-a-memory-pool}
54///
55///
56/// A `bdlma::BlockList` object is commonly used to supply memory to more
57/// elaborate memory managers that distribute parts of each (larger) allocated
58/// memory block supplied by the `bdlma::BlockList` object. The `my_StrPool`
59/// memory pool manager shown below requests relatively large blocks of memory
60/// from its `bdlma::BlockList` member object and distributes, via its
61/// `allocate` method, memory chunks of varying sizes from each block.
62///
63/// First, we define the interface of our `my_StrPool` class:
64/// @code
65/// // my_strpool.h
66///
67/// class my_StrPool {
68///
69/// // DATA
70/// bsls::Types::size_type d_blockSize; // size of current memory block
71///
72/// char *d_block_p; // current free memory block
73///
74/// bsls::Types::IntPtr d_cursor; // offset to next available byte
75/// // in block
76///
77/// bdlma::BlockList d_blockList; // supplies managed memory blocks
78///
79/// private:
80/// // PRIVATE MANIPULATORS
81/// void *allocateBlock(bsls::Types::size_type numBytes);
82/// // Request a new memory block of at least the specified 'numBytes'
83/// // size and allocate the initial 'numBytes' from this block.
84/// // Return the address of the allocated memory. The behavior is
85/// // undefined unless '0 < numBytes'.
86///
87/// private:
88/// // NOT IMPLEMENTED
89/// my_StrPool(const my_StrPool&);
90/// my_StrPool& operator=(const my_StrPool&);
91///
92/// public:
93/// // CREATORS
94/// my_StrPool(bslma::Allocator *basicAllocator = 0);
95/// // Create a memory manager. Optionally specify a 'basicAllocator'
96/// // used to supply memory. If 'basicAllocator' is 0, the currently
97/// // installed default allocator is used.
98///
99/// ~my_StrPool();
100/// // Destroy this object and release all associated memory.
101///
102/// // MANIPULATORS
103/// void *allocate(bsls::Types::size_type numBytes);
104/// // Allocate the specified 'numBytes' of memory and return its
105/// // address. If 'numBytes' is 0, return 0 with no other effect.
106///
107/// void release();
108/// // Release all memory currently allocated through this object.
109/// };
110///
111/// // MANIPULATORS
112/// inline
113/// void my_StrPool::release()
114/// {
115/// d_blockList.release();
116/// d_block_p = 0;
117/// }
118/// @endcode
119/// Finally, we provide the implementation of our `my_StrPool` class:
120/// @code
121/// // my_strpool.cpp
122///
123/// enum {
124/// k_INITIAL_SIZE = 128, // initial block size
125///
126/// k_GROWTH_FACTOR = 2, // multiplicative factor by which to grow block
127///
128/// k_THRESHOLD = 128 // size beyond which an individual block may be
129/// // allocated if it doesn't fit in current block
130/// };
131///
132/// // PRIVATE MANIPULATORS
133/// void *my_StrPool::allocateBlock(bsls::Types::size_type numBytes)
134/// {
135/// assert(0 < numBytes);
136///
137/// if (k_THRESHOLD < numBytes) {
138/// // Alloc separate block if above threshold.
139///
140/// return (char *)d_blockList.allocate(numBytes); // RETURN
141/// }
142/// else {
143/// if (d_block_p) {
144/// // Do not increase block size if no current block.
145///
146/// d_blockSize *= k_GROWTH_FACTOR;
147/// }
148/// d_block_p = (char *)d_blockList.allocate(d_blockSize);
149/// d_cursor = numBytes;
150/// return d_block_p; // RETURN
151/// }
152/// }
153///
154/// // CREATORS
155/// my_StrPool::my_StrPool(bslma::Allocator *basicAllocator)
156/// : d_blockSize(k_INITIAL_SIZE)
157/// , d_block_p(0)
158/// , d_blockList(basicAllocator) // the blocklist knows about 'bslma_default'
159/// {
160/// }
161///
162/// my_StrPool::~my_StrPool()
163/// {
164/// assert(k_INITIAL_SIZE <= d_blockSize);
165/// assert(!d_block_p || (0 <= d_cursor &&
166/// static_cast<bsls::Types::Uint64>(d_cursor) <= d_blockSize));
167/// }
168///
169/// // MANIPULATORS
170/// void *my_StrPool::allocate(bsls::Types::size_type numBytes)
171/// {
172/// if (0 == numBytes) {
173/// return 0; // RETURN
174/// }
175///
176/// if (d_block_p && numBytes + d_cursor <= d_blockSize) {
177/// char *p = d_block_p + d_cursor;
178/// d_cursor += numBytes;
179/// return p; // RETURN
180/// }
181/// else {
182/// return allocateBlock(numBytes); // RETURN
183/// }
184/// }
185/// @endcode
186/// In the code shown above, the `my_StrPool` memory manager allocates from its
187/// `bdlma::BlockList` member object an initial memory block of size
188/// `k_INITIAL_SIZE`. This size is multiplied by `k_GROWTH_FACTOR` each time a
189/// depleted memory block is replaced by a newly-allocated block. The
190/// `allocate` method distributes memory from the current memory block
191/// piecemeal, except when the requested size either (1) is not available in the
192/// current block, or (2) exceeds the `k_THRESHOLD_SIZE`, in which case a
193/// separate memory block is allocated and returned. When the `my_StrPool`
194/// memory manager is destroyed, its `bdlma::BlockList` member object is also
195/// destroyed, which, in turn, automatically deallocates all of its managed
196/// memory blocks.
197/// @}
198/** @} */
199/** @} */
200
201/** @addtogroup bdl
202 * @{
203 */
204/** @addtogroup bdlma
205 * @{
206 */
207/** @addtogroup bdlma_blocklist
208 * @{
209 */
210
211#include <bdlscm_version.h>
212
213#include <bslma_allocator.h>
214#include <bslma_default.h>
215
216#include <bsls_alignmentutil.h>
217#include <bsls_types.h>
218
219
220namespace bdlma {
221
222 // ===============
223 // class BlockList
224 // ===============
225
226/// This class implements a low-level memory manager that allocates and
227/// manages a sequence of memory blocks -- each potentially of a different
228/// size as specified during the invocation of the `allocate` method.
229/// Allocated blocks may be efficiently deallocated individually, i.e.,
230/// potentially in constant time depending on the supplied allocator. The
231/// `release` method deallocates the entire sequence of memory blocks, as
232/// does the destructor.
233///
234/// See @ref bdlma_blocklist
236
237 // TYPES
238
239 /// This `struct` overlays the beginning of each managed block of
240 /// allocated memory, implementing a doubly-linked list of managed
241 /// blocks, and thereby enabling constant-time deletions from, as well
242 /// as additions to, the list of blocks.
243 struct Block {
244
245 Block *d_next_p; // next pointer
246
247 Block **d_addrPrevNext; // enable delete
248
249 bsls::AlignmentUtil::MaxAlignedType d_memory; // force
250 // alignment
251 };
252
253 // DATA
254 Block *d_head_p; // address of first block of memory (or
255 // 0)
256
257 bslma::Allocator *d_allocator_p; // memory allocator (held, not owned)
258
259 private:
260 // NOT IMPLEMENTED
261 BlockList(const BlockList&);
262 BlockList& operator=(const BlockList&);
263
264 public:
265 // CREATORS
266
267 /// Create an empty block list suitable for managing memory blocks of
268 /// varying sizes. Optionally specify a `basicAllocator` used to supply
269 /// memory. If `basicAllocator` is 0, the currently installed default
270 /// allocator is used.
271 explicit
272 BlockList(bslma::Allocator *basicAllocator = 0);
273
274 /// Destroy this object and deallocate all outstanding memory blocks
275 /// managed by this object.
277
278 // MANIPULATORS
279
280 /// Return the address of a contiguous block of memory of the specified
281 /// `size` (in bytes). If `size` is 0, no memory is allocated and 0 is
282 /// returned. The returned memory is guaranteed to be maximally
283 /// aligned.
285
286 /// Return the memory at the specified `address` back to the associated
287 /// allocator. If `address` is 0, this function has no effect. The
288 /// behavior is undefined unless `address` was allocated by this object,
289 /// and has not already been deallocated.
290 void deallocate(void *address);
291
292 /// Deallocate all memory blocks currently managed by this object,
293 /// returning it to its default-constructed state.
294 void release();
295
296 // Aspects
297
298 /// Return the allocator used by this object to allocate memory.
300};
301
302// ============================================================================
303// INLINE DEFINITIONS
304// ============================================================================
305
306 // ---------------
307 // class BlockList
308 // ---------------
309
310// CREATORS
311inline
312BlockList::BlockList(bslma::Allocator *basicAllocator)
313: d_head_p(0)
314, d_allocator_p(bslma::Default::allocator(basicAllocator))
315{
316}
317
318// Aspects
319
320inline
322{
323 return d_allocator_p;
324}
325
326} // close package namespace
327
328
329#endif
330
331// ----------------------------------------------------------------------------
332// Copyright 2016 Bloomberg Finance L.P.
333//
334// Licensed under the Apache License, Version 2.0 (the "License");
335// you may not use this file except in compliance with the License.
336// You may obtain a copy of the License at
337//
338// http://www.apache.org/licenses/LICENSE-2.0
339//
340// Unless required by applicable law or agreed to in writing, software
341// distributed under the License is distributed on an "AS IS" BASIS,
342// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
343// See the License for the specific language governing permissions and
344// limitations under the License.
345// ----------------------------- END-OF-FILE ----------------------------------
346
347/** @} */
348/** @} */
349/** @} */
Definition bdlma_blocklist.h:235
void * allocate(bsls::Types::size_type size)
void deallocate(void *address)
bslma::Allocator * allocator() const
Return the allocator used by this object to allocate memory.
Definition bdlma_blocklist.h:321
Definition bslma_allocator.h:457
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlma_alignedallocator.h:276
Definition balxml_encoderoptions.h:68
AlignmentToType< BSLS_MAX_ALIGNMENT >::Type MaxAlignedType
Definition bsls_alignmentutil.h:282
std::size_t size_type
Definition bsls_types.h:124