BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlma_alignedallocator.h
Go to the documentation of this file.
1/// @file bdlma_alignedallocator.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlma_alignedallocator.h -*-C++-*-
8#ifndef INCLUDED_BDLMA_ALIGNEDALLOCATOR
9#define INCLUDED_BDLMA_ALIGNEDALLOCATOR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id$")
13
14/// @defgroup bdlma_alignedallocator bdlma_alignedallocator
15/// @brief Provide a protocol for memory allocators that support alignment.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlma
19/// @{
20/// @addtogroup bdlma_alignedallocator
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlma_alignedallocator-purpose"> Purpose</a>
25/// * <a href="#bdlma_alignedallocator-classes"> Classes </a>
26/// * <a href="#bdlma_alignedallocator-description"> Description </a>
27/// * <a href="#bdlma_alignedallocator-usage"> Usage </a>
28/// * <a href="#bdlma_alignedallocator-example-1-implementing-bdlma-alignedallocator"> Example 1: Implementing bdlma::AlignedAllocator </a>
29/// * <a href="#bdlma_alignedallocator-example-2-using-the-bdlma-alignedallocator-protocol"> Example 2: Using the bdlma::AlignedAllocator Protocol </a>
30///
31/// # Purpose {#bdlma_alignedallocator-purpose}
32/// Provide a protocol for memory allocators that support alignment.
33///
34/// # Classes {#bdlma_alignedallocator-classes}
35///
36/// - bdlma::AlignedAllocator: protocol for aligned memory allocators
37///
38/// @see bslma_allocator
39///
40/// # Description {#bdlma_alignedallocator-description}
41/// This component provides an implementation,
42/// `bdlma::AlignedAllocator`, of the base-level protocol (pure abstract
43/// interface) class, `bslma::Allocator`, providing the ability to allocate raw
44/// memory with a specified alignment. The following inheritance diagram shows
45/// the classes involved and their methods:
46/// @code
47/// ,----------------------.
48/// ( bdlma::AlignedAllocator )
49/// `----------------------'
50/// | allocateAligned
51/// V
52/// ,----------------.
53/// ( bslma::Allocator )
54/// `----------------'
55/// allocate
56/// deallocate
57/// @endcode
58/// The `allocateAligned` method supplies the address of a contiguous block of
59/// allocated memory of at least the indicated size, that is aligned to a given
60/// boundary. Note that this behavior is similar to the behavior of the POSIX
61/// function @ref posix_memalign .
62///
63/// ## Usage {#bdlma_alignedallocator-usage}
64///
65///
66/// This section illustrates intended use of this component.
67///
68/// ### Example 1: Implementing bdlma::AlignedAllocator {#bdlma_alignedallocator-example-1-implementing-bdlma-alignedallocator}
69///
70///
71/// The `bdlma::AlignedAllocator` protocol provided in this component defines a
72/// bilateral contract between suppliers and consumers of raw aligned memory.
73/// In order for the `bdlma::AlignedAllocator` interface to be useful, we must
74/// supply a concrete allocator that implements it.
75///
76/// In this example, we demonstrate how to adapt @ref posix_memalign on Linux and
77/// AIX, `memalign` on SunOS and `_aligned_malloc` on Windows, to this protocol
78/// base class:
79///
80/// First, we specify the interface of the concrete implementation of
81/// 'MyAlignedAllocator:
82/// @code
83/// // myposixmemalignallocator.h
84/// // ...
85///
86/// class MyAlignedAllocator: public bdlma::AlignedAllocator {
87/// // This class is a sample concrete implementation of the
88/// // 'bdlma::AlignedAllocator' protocol that provides direct access to
89/// // the system-supplied 'posix_memalign' and 'free' on Linux and AIX
90/// // platforms, 'memalign' and 'free' on SunOS, or '_aligned_malloc' and
91/// // '_aligned_free' on Windows.
92///
93/// private:
94/// // NOT IMPLEMENTED
95/// MyAlignedAllocator(const MyAlignedAllocator&);
96/// MyAlignedAllocator& operator=(const MyAlignedAllocator&);
97///
98/// public:
99/// // CREATORS
100/// MyAlignedAllocator();
101/// // Create a 'MyAlignedAllocator' object. Note that all objects of
102/// // this class share the same underlying resource.
103///
104/// virtual ~MyAlignedAllocator();
105/// // Destroy this object. Note that destroying this object has no
106/// // effect on any outstanding allocated memory.
107///
108/// // MANIPULATORS
109/// virtual void *allocate(bsls::Types::size_type size);
110/// // Return a newly allocated block of memory of (at least) the
111/// // specified positive 'size' (in bytes). If 'size' is 0, a null
112/// // pointer is returned with no other effect. If this allocator
113/// // cannot return the requested number of bytes, then it will throw
114/// // an 'std::bad_alloc' exception in an exception-enabled build, or
115/// // else it will abort the program in a non-exception build. The
116/// // behavior is undefined unless '0 <= size'. Note that the
117/// // alignment of the address returned conforms to the platform
118/// // requirement for any object of the 'size'. Also note that global
119/// // 'operator new' is *not* called when 'size' is 0 (in order to
120/// // avoid having to acquire a lock, and potential contention in
121/// // multi-threaded programs).
122///
123/// virtual void *allocateAligned(bsls::Types::size_type size,
124/// bsls::Types::size_type alignment);
125/// // Return the address of a newly allocated block of memory of at
126/// // least the specified positive 'size' (in bytes), sufficiently
127/// // aligned such that the returned 'address' satisfies, for the
128/// // specified 'alignment', '0 == (address & (alignment - 1))'. If
129/// // 'size' is 0, a null pointer is returned with no other effect.
130/// // If the requested number of appropriately aligned bytes cannot be
131/// // returned, then a 'bsl::bad_alloc' exception is thrown, or in a
132/// // non-exception build the program is terminated. The behavior is
133/// // undefined unless 'alignment' is both a multiple of
134/// // 'sizeof(void *)' and an integral non-negative power of two.
135///
136/// virtual void deallocate(void *address);
137/// // Return the memory block at the specified 'address' back to this
138/// // allocator. If 'address' is 0, this function has no effect. The
139/// // behavior is undefined unless 'address' was allocated using this
140/// // allocator object and has not already been deallocated.
141/// };
142/// // ...
143/// @endcode
144/// Then, we implement the creators, trivially, as this class contains no
145/// instance data members.
146/// @code
147/// // CREATORS
148/// MyAlignedAllocator::MyAlignedAllocator()
149/// {
150/// }
151///
152/// MyAlignedAllocator::~MyAlignedAllocator()
153/// {
154/// }
155/// @endcode
156/// Now, we define the virtual methods of `MyAlignedAllocator`. Note that these
157/// definitions are not `inline`, as they would not be inlined when invoked from
158/// the base class (the typical usage in this case):
159/// @code
160/// // MANIPULATORS
161/// void *MyAlignedAllocator::allocate(bsls::Types::size_type size)
162/// {
163/// if (0 == size) {
164/// return 0; // RETURN
165/// }
166///
167/// int alignment = bsls::AlignmentUtil::calculateAlignmentFromSize(size);
168/// return allocateAligned(size, alignment);
169/// }
170///
171/// void *MyAlignedAllocator::allocateAligned(bsls::Types::size_type size,
172/// bsls::Types::size_type alignment)
173/// {
174/// BSLS_ASSERT_SAFE(0 == (alignment & (alignment - 1)));
175/// BSLS_ASSERT_SAFE(0 == (alignment % sizeof(void *)));
176///
177/// if (0 == size) {
178/// return 0; // RETURN
179/// }
180///
181/// void *ret = 0;
182///
183/// #ifdef BSLS_PLATFORM_OS_WINDOWS
184/// errno = 0;
185/// ret = _aligned_malloc(size, alignment);
186/// if (0 != errno) {
187/// bsls::BslExceptionUtil::throwBadAlloc();
188/// }
189/// #elif defined(BSLS_PLATFORM_OS_SOLARIS)
190/// ret = memalign(alignment, size);
191/// if (0 == ret) {
192/// bsls::BslExceptionUtil::throwBadAlloc();
193/// }
194/// #else
195/// int rc = ::posix_memalign(&ret, alignment, size);
196/// if (0 != rc) {
197/// bsls::BslExceptionUtil::throwBadAlloc();
198/// }
199/// #endif
200///
201/// return ret;
202/// }
203///
204/// void MyAlignedAllocator::deallocate(void *address)
205/// {
206/// if (0 == address) {
207/// return; // RETURN
208/// }
209/// #ifdef BSLS_PLATFORM_WINDOWS
210/// _aligned_free(address);
211/// #else
212/// ::free(address);
213/// #endif
214/// }
215/// @endcode
216/// Finally, we define a function `f` that instantiates an object of type
217/// `MyAlignedAllocator`:
218/// @code
219/// void f() {
220/// MyAlignedAllocator a;
221/// }
222/// @endcode
223/// Note that the memory is not released when the allocator goes out of scope.
224///
225/// ### Example 2: Using the bdlma::AlignedAllocator Protocol {#bdlma_alignedallocator-example-2-using-the-bdlma-alignedallocator-protocol}
226///
227///
228/// In this example we illustrate how to use the `bdlma::AlignedAllocator`
229/// protocol to allocate memory that is aligned to the beginning of a memory
230/// page. Third party libraries, for example device drivers that perform DMA
231/// access of device drivers, or some extreme optimizations to reduce the number
232/// of page faults, might require page aligned allocations.
233///
234/// First, we create an aligned allocator `myAlignedAllocator` using the class
235/// `MyAlignedAllocator` defined in the previous example, and obtain a
236/// `bdlma::AlignedAllocator` pointer to it:
237/// @code
238/// MyAlignedAllocator myAlignedAllocator;
239/// bdlma::AlignedAllocator *alignedAllocator = &myAlignedAllocator;
240/// @endcode
241/// Now, assuming a page size of 4K, we allocate a buffer of 1024 bytes of
242/// memory and indicate that it should be aligned on a 4096 boundary:
243/// @code
244/// char *address = (char *) alignedAllocator->allocateAligned(1024, 4096);
245/// @endcode
246/// Finally, we verify that the obtained address actually is aligned as
247/// expected:
248/// @code
249/// assert(0 == ((bsl::size_t)address & (4096 - 1)));
250/// @endcode
251/// @}
252/** @} */
253/** @} */
254
255/** @addtogroup bdl
256 * @{
257 */
258/** @addtogroup bdlma
259 * @{
260 */
261/** @addtogroup bdlma_alignedallocator
262 * @{
263 */
264
265#include <bslscm_version.h>
266
267#include <bslma_allocator.h>
268
269#include <bsls_annotation.h>
270#include <bsls_platform.h>
271#include <bsls_types.h>
272
273#include <bsl_cstddef.h>
274
275
276namespace bdlma {
277
278 // ======================
279 // class AlignedAllocator
280 // ======================
281
282/// This protocol provides a pure abstract interface and contract for
283/// clients and suppliers of raw aligned memory. If the requested memory
284/// cannot be returned, the contract requires that an `std::bad_alloc`
285/// exception be thrown.
286///
287/// See @ref bdlma_alignedallocator
289
290 public:
291 // MANIPULATORS
292
293 /// Return the address of a newly allocated block of memory of at least
294 /// the specified positive `size` (in bytes), sufficiently aligned such
295 /// that the returned `address` satisfies, for the specified
296 /// `alignment`, `0 == (address & (alignment - 1))`. If `size` is 0, a
297 /// null pointer is returned with no other effect. If the requested
298 /// number of appropriately aligned bytes cannot be returned, then a
299 /// `bsl::bad_alloc` exception is thrown, or in a non-exception build
300 /// the program is terminated. The behavior is undefined unless
301 /// `alignment` is both a multiple of `sizeof(void *)` and an integral
302 /// non-negative power of two.
304 bsls::Types::size_type alignment) = 0;
305};
306
307} // close package namespace
308
309
310#endif
311
312// ----------------------------------------------------------------------------
313// Copyright 2016 Bloomberg Finance L.P.
314//
315// Licensed under the Apache License, Version 2.0 (the "License");
316// you may not use this file except in compliance with the License.
317// You may obtain a copy of the License at
318//
319// http://www.apache.org/licenses/LICENSE-2.0
320//
321// Unless required by applicable law or agreed to in writing, software
322// distributed under the License is distributed on an "AS IS" BASIS,
323// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
324// See the License for the specific language governing permissions and
325// limitations under the License.
326// ----------------------------- END-OF-FILE ----------------------------------
327
328/** @} */
329/** @} */
330/** @} */
Definition bdlma_alignedallocator.h:288
virtual void * allocateAligned(bsls::Types::size_type size, bsls::Types::size_type alignment)=0
Definition bslma_allocator.h:457
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlma_alignedallocator.h:276
std::size_t size_type
Definition bsls_types.h:124