14 #ifndef STXXL_ALIGNED_ALLOC
15 #define STXXL_ALIGNED_ALLOC
19 #include <stxxl/bits/verbose.h>
20 #include <stxxl/bits/common/utils.h>
23 #ifndef STXXL_VERBOSE_ALIGNED_ALLOC
24 #define STXXL_VERBOSE_ALIGNED_ALLOC STXXL_VERBOSE2
27 __STXXL_BEGIN_NAMESPACE
29 template <
typename must_be_
int>
30 struct aligned_alloc_settings {
31 static bool may_use_realloc;
34 template <
typename must_be_
int>
35 bool aligned_alloc_settings<must_be_int>::may_use_realloc =
true;
48 template <
size_t ALIGNMENT>
49 inline void * aligned_alloc(
size_t size,
size_t meta_info_size = 0)
51 STXXL_VERBOSE2(
"stxxl::aligned_alloc<" << ALIGNMENT <<
">(), size = " << size <<
", meta info size = " << meta_info_size);
52 #if !defined(STXXL_WASTE_MORE_MEMORY_FOR_IMPROVED_ACCESS_AFTER_ALLOCATED_MEMORY_CHECKS)
58 size_t alloc_size = ALIGNMENT +
sizeof(
char *) + meta_info_size + size;
59 char * buffer = (
char *)std::malloc(alloc_size);
69 size_t alloc_size = ALIGNMENT * div_ceil(
sizeof(
char *) + meta_info_size, ALIGNMENT) + size;
71 if (posix_memalign((
void **)&buffer, ALIGNMENT, alloc_size) != 0)
72 throw std::bad_alloc();
75 throw std::bad_alloc();
76 #ifdef STXXL_ALIGNED_CALLOC
77 memset(buffer, 0, alloc_size);
79 char * reserve_buffer = buffer +
sizeof(
char *) + meta_info_size;
80 char * result = reserve_buffer + ALIGNMENT -
81 (((
unsigned long)reserve_buffer) % (ALIGNMENT)) - meta_info_size;
82 STXXL_VERBOSE2(
"stxxl::aligned_alloc<" << ALIGNMENT <<
">() address " << (
void *)result <<
" lost " << (result - buffer) <<
" bytes");
83 assert(
long(result - buffer) >=
long(
sizeof(
char *)));
87 size_t realloc_size = (result - buffer) + meta_info_size + size;
88 if (realloc_size < alloc_size && aligned_alloc_settings<int>::may_use_realloc) {
89 char * realloced = (
char *)std::realloc(buffer, realloc_size);
90 if (buffer != realloced) {
93 STXXL_ERRMSG(
"stxxl::aligned_alloc: disabling realloc()");
95 aligned_alloc_settings<int>::may_use_realloc =
false;
96 return aligned_alloc<ALIGNMENT>(size, meta_info_size);
98 assert(result + size <= buffer + realloc_size);
101 *(((
char **)result) - 1) = buffer;
102 STXXL_VERBOSE2(
"stxxl::aligned_alloc<" << ALIGNMENT <<
">(), allocated at " << (
void *)buffer <<
" returning " << (
void *)result);
103 STXXL_VERBOSE_ALIGNED_ALLOC(
"stxxl::aligned_alloc<" << ALIGNMENT <<
104 ">(size = " << size <<
", meta info size = " << meta_info_size <<
105 ") => buffer = " << (
void *)buffer <<
", ptr = " << (
void *)result);
110 template <
size_t ALIGNMENT>
112 aligned_dealloc(
void * ptr)
116 char * buffer = *(((
char **)ptr) - 1);
117 STXXL_VERBOSE_ALIGNED_ALLOC(
"stxxl::aligned_dealloc<" << ALIGNMENT <<
">(), ptr = " << ptr <<
", buffer = " << (
void *)buffer);
121 __STXXL_END_NAMESPACE
123 #endif // !STXXL_ALIGNED_ALLOC