util.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. /* util.c - memory functions.
  2. *
  3. * Copyright (c) 2020, Aleksey Kravchenko <[email protected]>
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any
  6. * purpose with or without fee is hereby granted.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  9. * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  10. * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  11. * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  12. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  13. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  14. * PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #include "util.h"
  17. #if defined(HAS_POSIX_ALIGNED_ALLOC)
  18. #include <errno.h>
  19. void* rhash_px_aalloc(size_t alignment, size_t size)
  20. {
  21. void* ptr;
  22. if ((errno = posix_memalign(&ptr, alignment, size)) != 0)
  23. return NULL;
  24. return ptr;
  25. }
  26. #elif defined(HAS_GENERIC_ALIGNED_ALLOC)
  27. #include <assert.h>
  28. #include <stdlib.h>
  29. void* rhash_aligned_alloc(size_t alignment, size_t size)
  30. {
  31. unsigned char* block = (unsigned char*)malloc(size + alignment);
  32. assert((alignment & (alignment - 1)) == 0);
  33. assert(alignment >= sizeof(void*));
  34. if (block) {
  35. const size_t alignment_mask = (alignment - 1);
  36. unsigned char* basement = block + sizeof(void*);
  37. size_t offset = ((unsigned char*)0 - basement) & alignment_mask;
  38. void** result = (void**)(basement + offset);
  39. assert((((unsigned char*)result - (unsigned char*)0) % alignment) == 0);
  40. result[-1] = block; /* store original pointer */
  41. return result;
  42. }
  43. return NULL;
  44. }
  45. void rhash_aligned_free(void* ptr)
  46. {
  47. void** pfree = (void**)ptr;
  48. if (ptr)
  49. free(pfree[-1]);
  50. }
  51. #else
  52. typedef int dummy_declaration_required_by_strict_iso_c;
  53. #endif /* HAS_POSIX_ALIGNED_ALLOC / HAS_GENERIC_ALIGNED_ALLOC */