http://stxxl.sourceforge.net
<dementiev@mpi-sb.mpg.de>
<beckmann@cs.uni-frankfurt.de>
http://www.boost.org/LICENSE_1_0.txt
#ifndef STXXL_ALIGNED_ALLOC
#define STXXL_ALIGNED_ALLOC
#include <cstdlib>
#include <cassert>
#include <stxxl/bits/verbose.h>
#include <stxxl/bits/common/utils.h>
#ifndef STXXL_VERBOSE_ALIGNED_ALLOC
#define STXXL_VERBOSE_ALIGNED_ALLOC STXXL_VERBOSE2
#endif
__STXXL_BEGIN_NAMESPACE
template <typename must_be_int>
struct aligned_alloc_settings {
static bool may_use_realloc;
};
template <typename must_be_int>
bool aligned_alloc_settings<must_be_int>::may_use_realloc = true;
template <size_t ALIGNMENT>
inline void * aligned_alloc(size_t size, size_t meta_info_size = 0)
{
STXXL_VERBOSE2("stxxl::aligned_alloc<" << ALIGNMENT << ">(), size = " << size << ", meta info size = " << meta_info_size);
#if !defined(STXXL_WASTE_MORE_MEMORY_FOR_IMPROVED_ACCESS_AFTER_ALLOCATED_MEMORY_CHECKS)
size_t alloc_size = ALIGNMENT + sizeof(char *) + meta_info_size + size;
char * buffer = (char *)std::malloc(alloc_size);
#else
size_t alloc_size = ALIGNMENT * div_ceil(sizeof(char *) + meta_info_size, ALIGNMENT) + size;
char * buffer;
if (posix_memalign((void **)&buffer, ALIGNMENT, alloc_size) != 0)
throw std::bad_alloc();
#endif
if (buffer == NULL)
throw std::bad_alloc();
#ifdef STXXL_ALIGNED_CALLOC
memset(buffer, 0, alloc_size);
#endif
char * reserve_buffer = buffer + sizeof(char *) + meta_info_size;
char * result = reserve_buffer + ALIGNMENT -
(((unsigned long)reserve_buffer) % (ALIGNMENT)) - meta_info_size;
STXXL_VERBOSE2("stxxl::aligned_alloc<" << ALIGNMENT << ">() address " << (void *)result << " lost " << (result - buffer) << " bytes");
assert(long(result - buffer) >= long(sizeof(char *)));
size_t realloc_size = (result - buffer) + meta_info_size + size;
if (realloc_size < alloc_size && aligned_alloc_settings<int>::may_use_realloc) {
char * realloced = (char *)std::realloc(buffer, realloc_size);
if (buffer != realloced) {
STXXL_ERRMSG("stxxl::aligned_alloc: disabling realloc()");
std::free(realloced);
aligned_alloc_settings<int>::may_use_realloc = false;
return aligned_alloc<ALIGNMENT>(size, meta_info_size);
}
assert(result + size <= buffer + realloc_size);
}
*(((char **)result) - 1) = buffer;
STXXL_VERBOSE2("stxxl::aligned_alloc<" << ALIGNMENT << ">(), allocated at " << (void *)buffer << " returning " << (void *)result);
STXXL_VERBOSE_ALIGNED_ALLOC("stxxl::aligned_alloc<" << ALIGNMENT <<
">(size = " << size << ", meta info size = " << meta_info_size <<
") => buffer = " << (void *)buffer << ", ptr = " << (void *)result);
return result;
}
template <size_t ALIGNMENT>
inline void
aligned_dealloc(void * ptr)
{
if (!ptr)
return;
char * buffer = *(((char **)ptr) - 1);
STXXL_VERBOSE_ALIGNED_ALLOC("stxxl::aligned_dealloc<" << ALIGNMENT << ">(), ptr = " << ptr << ", buffer = " << (void *)buffer);
std::free(buffer);
}
__STXXL_END_NAMESPACE
#endif