DNA Calib 1.1
Project brief
Namespaces | Macros | Functions
AlignedMemoryResource.cpp File Reference
#include "pma/resources/AlignedMemoryResource.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
Include dependency graph for AlignedMemoryResource.cpp:

Namespaces

namespace  pma
 

Macros

#define ALIGNED_ALLOC(ptr, alignment, size)   ptr = alignedAlloc(size, alignment)
 
#define ALIGNED_FREE(ptr)   alignedFree(ptr)
 

Functions

std::uintptr_t alignAddress (std::uintptr_t address, std::size_t alignment)
 
template<typename T >
T * alignPointer (T *ptr, std::size_t alignment)
 
void * alignedAlloc (std::size_t size, std::size_t alignment)
 
void alignedFree (void *ptr)
 

Macro Definition Documentation

◆ ALIGNED_ALLOC

#define ALIGNED_ALLOC (   ptr,
  alignment,
  size 
)    ptr = alignedAlloc(size, alignment)

◆ ALIGNED_FREE

#define ALIGNED_FREE (   ptr)    alignedFree(ptr)

Function Documentation

◆ alignAddress()

std::uintptr_t alignAddress ( std::uintptr_t  address,
std::size_t  alignment 
)
inline
31 {
32 const std::size_t mask = alignment - 1ul;
33 assert((alignment & mask) == 0ul);
34 return (address + mask) & ~mask;
35 }

Referenced by alignPointer().

◆ alignedAlloc()

void * alignedAlloc ( std::size_t  size,
std::size_t  alignment 
)
44 {
45 const std::size_t actualSize = size + alignment;
46 char* pUnalignedChunk = new char[actualSize];
47 char* pAlignedChunk = alignPointer(pUnalignedChunk, alignment);
48 if (pAlignedChunk == pUnalignedChunk) {
49 // There was no need for additional alignment, so an artifical gap
50 // must be added to make room for the shift value
51 pAlignedChunk += alignment;
52 }
53 // Compute and write the shift value into the buffer (it is needed during
54 // deallocation to reconstruct by which amount was the given pointer
55 // offset to meet the alignment requirement)
56 std::ptrdiff_t shift = pAlignedChunk - pUnalignedChunk;
57 // The guaranteed storage size for the shift value is only one byte
58 assert(shift > 0 && shift <= 256);
59 pAlignedChunk[-1] = static_cast<char>(shift & 0xFF);
60 return static_cast<void*>(pAlignedChunk);
61 }
T * alignPointer(T *ptr, std::size_t alignment)
Definition: AlignedMemoryResource.cpp:38

References alignPointer().

◆ alignedFree()

void alignedFree ( void *  ptr)
63 {
64 if (ptr) {
65 auto pAlignedChunk = reinterpret_cast<char*>(ptr);
66 std::ptrdiff_t shift = pAlignedChunk[-1];
67 // There is no 0 alignment, so the value is reused to actually denote alignment by 256
68 if (shift == 0) {
69 shift = 256;
70 }
71 // Compute the actual start address of the chunk, prior to aligning it's address
72 auto pUnalignedChunk = pAlignedChunk - shift;
73 delete[] pUnalignedChunk;
74 }
75 }

◆ alignPointer()

template<typename T >
T * alignPointer ( T *  ptr,
std::size_t  alignment 
)
inline
38 {
39 const std::uintptr_t address = reinterpret_cast<std::uintptr_t>(ptr);
40 const std::uintptr_t aligned = alignAddress(address, alignment);
41 return reinterpret_cast<T*>(aligned);
42 }
std::uintptr_t alignAddress(std::uintptr_t address, std::size_t alignment)
Definition: AlignedMemoryResource.cpp:31

References alignAddress().

Referenced by alignedAlloc().