| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- /* util.c - memory functions.
- *
- * Copyright (c) 2020, Aleksey Kravchenko <[email protected]>
- *
- * 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 */
|