14 #ifndef FOXXLL_COMMON_ALIGNED_ALLOC_HEADER 15 #define FOXXLL_COMMON_ALIGNED_ALLOC_HEADER 28 template <
typename MustBeInt>
33 template <
typename MustBeInt>
47 template <
size_t Alignment>
51 <<
"foxxll::aligned_alloc<" << Alignment <<
">(), " 52 <<
"size = " << size <<
", meta info size = " << meta_info_size;
53 #if !defined(FOXXLL_WASTE_MORE_MEMORY_FOR_IMPROVED_ACCESS_AFTER_ALLOCATED_MEMORY_CHECKS) 59 size_t alloc_size = Alignment +
sizeof(
char*) + meta_info_size + size;
60 auto* buffer =
static_cast<char*
>(
std::malloc(alloc_size));
70 size_t alloc_size = Alignment *
div_ceil(
sizeof(
char*) + meta_info_size, Alignment) + size;
72 if (posix_memalign((
void**)&buffer, Alignment, alloc_size) != 0)
73 throw std::bad_alloc();
75 if (buffer ==
nullptr)
76 throw std::bad_alloc();
77 #ifdef FOXXLL_ALIGNED_CALLOC 78 memset(buffer, 0, alloc_size);
80 char* reserve_buffer = buffer +
sizeof(
char*) + meta_info_size;
81 char* result = reserve_buffer + Alignment -
82 (
reinterpret_cast<size_t>(reserve_buffer) % Alignment) - meta_info_size;
84 <<
"foxxll::aligned_alloc<" << Alignment <<
">() address " 85 <<
static_cast<void*
>(result) <<
" lost " << (result - buffer) <<
" bytes";
89 assert(
long(result - buffer) >=
long(
sizeof(
char*)));
93 size_t realloc_size =
static_cast<size_t>(result - buffer) + meta_info_size + size;
95 auto* realloced =
static_cast<char*
>(
std::realloc(buffer, realloc_size));
96 if (buffer != realloced) {
99 TLX_LOG1 <<
"foxxll::aligned_alloc: disabling realloc()";
102 return aligned_alloc<Alignment>(size, meta_info_size);
104 assert(result + size <= buffer + realloc_size);
107 *(
reinterpret_cast<char**
>(result) - 1) = buffer;
109 <<
"foxxll::aligned_alloc<" << Alignment <<
">(), allocated at " 110 <<
static_cast<void*
>(buffer) <<
" returning " << static_cast<void*>(result);
113 <<
"foxxll::aligned_alloc<" << Alignment
114 <<
">(size = " << size <<
", meta info size = " << meta_info_size
115 <<
") => buffer = " <<
static_cast<void*
>(buffer) <<
", ptr = " << static_cast<void*>(result);
120 template <
size_t Alignment>
126 char* buffer = *(
static_cast<char**
>(ptr) - 1);
128 <<
"foxxll::aligned_dealloc<" << Alignment <<
">(), " 129 <<
"ptr = " << ptr <<
", buffer = " <<
static_cast<void*
>(buffer);
135 #endif // !FOXXLL_COMMON_ALIGNED_ALLOC_HEADER
static bool may_use_realloc
void aligned_dealloc(void *ptr)
constexpr bool debug_aligned_alloc
std::remove_const< Integral >::type div_ceil(Integral n, Integral2 d)
void * malloc(size_t size) NOEXCEPT
exported malloc symbol that overrides loading from libc
void * aligned_alloc(size_t size, size_t meta_info_size=0)
#define TLX_LOGC(cond)
Explicitly specify the condition for logging.
void free(void *ptr) NOEXCEPT
exported free symbol that overrides loading from libc
void * realloc(void *ptr, size_t size) NOEXCEPT
exported realloc() symbol that overrides loading from libc