#include "util.h"
#if defined(HAS_POSIX_ALIGNED_ALLOC)
#include <errno.h>
void* rhash_px_aalloc(size_t alignment, size_t size)
{
void* ptr;
if ((errno = posix_memalign(&ptr, alignment, size)) != 0)
return NULL;
return ptr;
}
#elif defined(HAS_GENERIC_ALIGNED_ALLOC)
#include <assert.h>
#include <stdlib.h>
void* rhash_aligned_alloc(size_t alignment, size_t size)
{
unsigned char* block = (unsigned char*)malloc(size + alignment);
assert((alignment & (alignment - 1)) == 0);
assert(alignment >= sizeof(void*));
if (block) {
const size_t alignment_mask = (alignment - 1);
unsigned char* basement = block + sizeof(void*);
size_t offset = ((unsigned char*)0 - basement) & alignment_mask;
void** result = (void**)(basement + offset);
assert((((unsigned char*)result - (unsigned char*)0) % alignment) == 0);
result[-1] = block;
return result;
}
return NULL;
}
void rhash_aligned_free(void* ptr)
{
void** pfree = (void**)ptr;
if (ptr)
free(pfree[-1]);
}
#else
typedef int dummy_declaration_required_by_strict_iso_c;
#endif