zutil_p.h 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /* zutil_p.h -- Private inline functions used internally in zlib-ng
  2. * For conditions of distribution and use, see copyright notice in zlib.h
  3. */
  4. #ifndef ZUTIL_P_H
  5. #define ZUTIL_P_H
  6. #if defined(__APPLE__) || defined(HAVE_POSIX_MEMALIGN) || defined(HAVE_ALIGNED_ALLOC)
  7. # include <stdlib.h>
  8. #elif defined(__FreeBSD__)
  9. # include <stdlib.h>
  10. # include <malloc_np.h>
  11. #else
  12. # include <malloc.h>
  13. #endif
  14. /* Function to allocate 16 or 64-byte aligned memory */
  15. static inline void *zng_alloc(size_t size) {
  16. #ifdef HAVE_ALIGNED_ALLOC
  17. /* Size must be a multiple of alignment */
  18. size = (size + (64 - 1)) & ~(64 - 1);
  19. return (void *)aligned_alloc(64, size); /* Defined in C11 */
  20. #elif defined(HAVE_POSIX_MEMALIGN)
  21. void *ptr;
  22. return posix_memalign(&ptr, 64, size) ? NULL : ptr;
  23. #elif defined(_WIN32)
  24. return (void *)_aligned_malloc(size, 64);
  25. #elif defined(__APPLE__)
  26. /* Fallback for when posix_memalign and aligned_alloc are not available.
  27. * On macOS, it always aligns to 16 bytes. */
  28. return (void *)malloc(size);
  29. #else
  30. return (void *)memalign(64, size);
  31. #endif
  32. }
  33. /* Function that can free aligned memory */
  34. static inline void zng_free(void *ptr) {
  35. #if defined(_WIN32)
  36. _aligned_free(ptr);
  37. #else
  38. free(ptr);
  39. #endif
  40. }
  41. /* Use memcpy instead of memcmp to avoid older compilers not converting memcmp calls to
  42. unaligned comparisons when unaligned access is supported. */
  43. static inline int32_t zng_memcmp_2(const void *src0, const void *src1) {
  44. uint16_t src0_cmp, src1_cmp;
  45. memcpy(&src0_cmp, src0, sizeof(src0_cmp));
  46. memcpy(&src1_cmp, src1, sizeof(src1_cmp));
  47. return src0_cmp != src1_cmp;
  48. }
  49. static inline int32_t zng_memcmp_4(const void *src0, const void *src1) {
  50. uint32_t src0_cmp, src1_cmp;
  51. memcpy(&src0_cmp, src0, sizeof(src0_cmp));
  52. memcpy(&src1_cmp, src1, sizeof(src1_cmp));
  53. return src0_cmp != src1_cmp;
  54. }
  55. static inline int32_t zng_memcmp_8(const void *src0, const void *src1) {
  56. uint64_t src0_cmp, src1_cmp;
  57. memcpy(&src0_cmp, src0, sizeof(src0_cmp));
  58. memcpy(&src1_cmp, src1, sizeof(src1_cmp));
  59. return src0_cmp != src1_cmp;
  60. }
  61. #endif