Provide a namespace for enumerating memory alignment strategies.
More...
Namespaces |
namespace | bsls |
Detailed Description
- Outline
-
-
- Purpose:
- Provide a namespace for enumerating memory alignment strategies.
-
- Classes:
-
- See also:
- Component bsls_alignmentutil
-
- Description:
- This component provides a namespace,
bsls::Alignment
, for enumerating alignment strategies, and provides a function, toAscii
, that converts each of the enumerators to its corresponding string representation.
-
- Alignment Strategy:
- This component supports three alignment strategies: 1) MAXIMUM ALIGNMENT, 2) NATURAL ALIGNMENT, and 3) 1-BYTE ALIGNMENT.
-
MAXIMUM ALIGNMENT: This strategy, as indicated by the enumerator
BSLS_MAXIMUM
, specifies that a memory block be aligned as per the most restrictive alignment requirement on the host platform.
-
NATURAL ALIGNMENT: This strategy, as indicated by the enumerator
BSLS_NATURAL
, specifies that a memory block be aligned based on the size (in bytes) of that block. An object of a fundamental type (int
, etc.) is naturally aligned when its size evenly divides its address. An object of an aggregate type has natural alignment if the alignment of the most-restrictively aligned sub-object evenly divides the address of the aggregate. Natural alignment is always at least as restrictive as the compiler's required alignment.
-
1-BYTE ALIGNMENT: This strategy, as indicated by the enumerator
BSLS_BYTEALIGNED
, specifies that a memory block may be aligned arbitrarily on any 1-byte boundary. This is the least restrictive alignment requirement.
-
- Usage:
- Suppose that we want to create a static function,
allocateFromBuffer
, that takes a buffer, the size of the buffer, a cursor indicating a position within the buffer, an allocation request size, and a memory alignment strategy; allocateFromBuffer
returns a pointer to a block of memory, wholly contained within the buffer, having the specified size and alignment. As a side-effect, the cursor is updated to refer to the next available free byte in the buffer. Such a function could be used by a memory manager to satisfy allocation requests from internally-managed buffers. Clients of this function indicate which alignment strategy to use based on their specific requirements.
- Our
allocateFromBuffer
function depends on an alignment utility, my_AlignmentUtil
, whose minimal interface is limited to that required by this usage example. (See the bsls_alignmentutil
component for a more realistic alignment utility.): struct my_AlignmentUtil {
enum {
MY_MAX_PLATFORM_ALIGNMENT = 8
};
static int calculateAlignmentFromSize(int size);
static int calculateAlignmentOffset(const void *address,
int alignment);
};
The definition of our allocateFromBuffer
function is as follows: First we assert the function pre-conditions: assert(cursor);
assert(buffer);
assert(0 <= bufferSize);
assert(0 < size);
Then, based on the alignment strategy
, we calculate the alignment value that can satisfy the allocation request. In the case of bsls::Alignment::BSLS_NATURAL
, we calculate the alignment from size
; for bsls::Alignment::BSLS_MAXIMUM
, we use the platform-dependent my_AlignmentUtil::MY_MAX_PLATFORM_ALIGNMENT
value; and for bsls::Alignment::BSLS_BYTEALIGNED
, we simply use 1: const int alignment =
strategy == bsls::Alignment::BSLS_NATURAL
? my_AlignmentUtil::calculateAlignmentFromSize(size)
: strategy == bsls::Alignment::BSLS_MAXIMUM
? my_AlignmentUtil::MY_MAX_PLATFORM_ALIGNMENT
: 1;
Now we calculate the offset from the current cursor
value that can satisfy the alignment
requirements: const int offset = my_AlignmentUtil::calculateAlignmentOffset(
buffer + *cursor,
alignment);
Next we check if the available free memory in buffer
can satisfy the allocation request; 0 is returned if the request cannot be satisfied: if (*cursor + offset + size > bufferSize) {
return 0;
}
void *result = &buffer[*cursor + offset];
*cursor += offset + size;
Finally, return the address of the correctly aligned memory block: The allocateFromBuffer
function may be used by a memory manager that needs to appropriately align memory blocks that are allocated from internally-managed buffers. For an example, see the bslma_bufferimputil
component.