|
35 | 35 | // Date: 17 October 2025 |
36 | 36 | //***************************************************************************/ |
37 | 37 |
|
| 38 | +#include <assert.h> |
38 | 39 | #include <stdlib.h> |
| 40 | +#include <stdint.h> |
39 | 41 |
|
40 | 42 | //////////////////////////////////////////////////////////////////////////////// |
41 | 43 | // OS detection definitions for C only |
|
59 | 61 | #define OJPH_EXPORT |
60 | 62 | #endif |
61 | 63 |
|
62 | | -//////////////////////////////////////////////////////////////////////////// |
| 64 | +//////////////////////////////////////////////////////////////////////////////// |
63 | 65 | #ifdef OJPH_OS_WINDOWS |
64 | 66 | OJPH_EXPORT void* ojph_aligned_malloc(size_t alignment, size_t size) |
65 | 67 | { |
| 68 | + assert(alignment != 0 && (alignment & (alignment - 1)) == 0); |
66 | 69 | return _aligned_malloc(size, alignment); |
67 | 70 | } |
68 | 71 |
|
69 | 72 | OJPH_EXPORT void ojph_aligned_free(void* pointer) |
70 | 73 | { |
71 | 74 | _aligned_free(pointer); |
72 | 75 | } |
73 | | -#else |
| 76 | +#elif (defined OJPH_ALIGNED_ALLOC_EXISTS) |
74 | 77 | void* ojph_aligned_malloc(size_t alignment, size_t size) |
75 | 78 | { |
| 79 | + assert(alignment != 0 && (alignment & (alignment - 1)) == 0); |
76 | 80 | return aligned_alloc(alignment, size); |
77 | 81 | } |
78 | 82 |
|
79 | 83 | void ojph_aligned_free(void* pointer) |
80 | 84 | { |
81 | 85 | free(pointer); |
82 | 86 | } |
| 87 | +#elif (defined OJPH_POSIX_MEMALIGN_EXISTS) |
| 88 | + void* ojph_aligned_malloc(size_t alignment, size_t size) |
| 89 | + { |
| 90 | + assert(alignment != 0 && (alignment & (alignment - 1)) == 0); |
| 91 | + void *p = NULL; |
| 92 | + int e = posix_memalign(&p, alignment, size); |
| 93 | + return (e ? NULL : p); |
| 94 | + } |
| 95 | + |
| 96 | + void ojph_aligned_free(void* pointer) |
| 97 | + { |
| 98 | + free(pointer); |
| 99 | + } |
| 100 | +#else |
| 101 | + void* ojph_aligned_malloc(size_t alignment, size_t size) |
| 102 | + { |
| 103 | + assert(alignment != 0 && (alignment & (alignment - 1)) == 0); |
| 104 | + |
| 105 | + // emulate aligned_alloc |
| 106 | + void* orig_ptr = malloc(size + alignment + sizeof(void*)); |
| 107 | + if (orig_ptr == NULL) |
| 108 | + return NULL; // Allocation failed |
| 109 | + |
| 110 | + uintptr_t start_of_mem = (uintptr_t)orig_ptr + sizeof(void*); |
| 111 | + uintptr_t aligned_addr = (start_of_mem + alignment - 1) & ~(alignment - 1); |
| 112 | + |
| 113 | + void** ptr_to_orig_ptr = (void**)aligned_addr; |
| 114 | + ptr_to_orig_ptr[-1] = orig_ptr; |
| 115 | + |
| 116 | + return (void*)aligned_addr; |
| 117 | + } |
| 118 | + |
| 119 | + void ojph_aligned_free(void* pointer) |
| 120 | + { |
| 121 | + if (pointer) { |
| 122 | + // Retrieve the original pointer stored just before aligned pointer |
| 123 | + void** ptr_to_orig_ptr = (void**)pointer; |
| 124 | + void* orig_ptr = ptr_to_orig_ptr[-1]; |
| 125 | + |
| 126 | + free(orig_ptr); |
| 127 | + } |
| 128 | + } |
83 | 129 | #endif |
0 commit comments