diff options
Diffstat (limited to 'Utilities/cmlibrhash/librhash/util.c')
-rw-r--r-- | Utilities/cmlibrhash/librhash/util.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/Utilities/cmlibrhash/librhash/util.c b/Utilities/cmlibrhash/librhash/util.c new file mode 100644 index 0000000..8266460 --- /dev/null +++ b/Utilities/cmlibrhash/librhash/util.c @@ -0,0 +1,61 @@ +/* util.c - memory functions. + * + * Copyright (c) 2020, Aleksey Kravchenko <rhash.admin@gmail.com> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ +#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; /* store original pointer */ + 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 /* HAS_POSIX_ALIGNED_ALLOC / HAS_GENERIC_ALIGNED_ALLOC */ |