@@ -35,20 +35,28 @@ bool aws_allocator_is_valid(const struct aws_allocator *alloc) {
3535}
3636
3737static void * s_aligned_malloc (struct aws_allocator * allocator , size_t size ) {
38- (void )allocator ;
39- /* larger allocations should be aligned so that AVX and friends can avoid
40- * the extra preamble during unaligned versions of memcpy/memset on big buffers
41- * This will also accelerate hardware CRC and SHA on ARM chips
42- *
43- * 64 byte alignment for > page allocations on 64 bit systems
44- * 32 byte alignment for > page allocations on 32 bit systems
45- * 16 byte alignment for <= page allocations on 64 bit systems
46- * 8 byte alignment for <= page allocations on 32 bit systems
47- *
48- * We use PAGE_SIZE as the boundary because we are not aware of any allocations of
49- * this size or greater that are not data buffers
50- */
51- const size_t alignment = sizeof (void * ) * (size > (size_t )PAGE_SIZE ? 8 : 2 );
38+ size_t alignment = 0 ;
39+ if (allocator -> impl != NULL ) {
40+ alignment = (size_t )allocator -> impl ;
41+ } else {
42+ /**
43+ * For implicit alignment.
44+ * larger allocations should be aligned so that AVX and friends can avoid
45+ * the extra preamble during unaligned versions of memcpy/memset on big buffers
46+ * This will also accelerate hardware CRC and SHA on ARM chips
47+ *
48+ * 64 byte alignment for > page allocations on 64 bit systems
49+ * 32 byte alignment for > page allocations on 32 bit systems
50+ * 16 byte alignment for <= page allocations on 64 bit systems
51+ * 8 byte alignment for <= page allocations on 32 bit systems
52+ *
53+ * We use PAGE_SIZE as the boundary because we are not aware of any allocations of
54+ * this size or greater that are not data buffers.
55+ *
56+ * Unless there is a customized alignment size.
57+ */
58+ alignment = sizeof (void * ) * (size > (size_t )PAGE_SIZE ? 8 : 2 );
59+ }
5260#if !defined(_WIN32 )
5361 void * result = NULL ;
5462 int err = posix_memalign (& result , alignment , size );
@@ -146,26 +154,48 @@ static void *s_non_aligned_calloc(struct aws_allocator *allocator, size_t num, s
146154 return mem ;
147155}
148156
149- static struct aws_allocator default_allocator = {
157+ static struct aws_allocator s_default_allocator = {
150158 .mem_acquire = s_non_aligned_malloc ,
151159 .mem_release = s_non_aligned_free ,
152160 .mem_realloc = s_non_aligned_realloc ,
153161 .mem_calloc = s_non_aligned_calloc ,
154162};
155163
156164struct aws_allocator * aws_default_allocator (void ) {
157- return & default_allocator ;
165+ return & s_default_allocator ;
158166}
159167
160- static struct aws_allocator aligned_allocator = {
168+ static struct aws_allocator s_implicit_aligned_allocator = {
161169 .mem_acquire = s_aligned_malloc ,
162170 .mem_release = s_aligned_free ,
163171 .mem_realloc = s_aligned_realloc ,
164172 .mem_calloc = s_aligned_calloc ,
165173};
166174
167175struct aws_allocator * aws_aligned_allocator (void ) {
168- return & aligned_allocator ;
176+ return & s_implicit_aligned_allocator ;
177+ }
178+
179+ struct aws_allocator * aws_explicit_aligned_allocator_new (size_t customized_alignment ) {
180+ if (customized_alignment == 0 || (customized_alignment & (customized_alignment - 1 )) != 0 ||
181+ customized_alignment % sizeof (void * ) != 0 ) {
182+ /**
183+ * the alignment must be a power of two and a multiple of sizeof(void *) and non-zero.
184+ */
185+ aws_raise_error (AWS_ERROR_INVALID_ARGUMENT );
186+ return NULL ;
187+ }
188+ struct aws_allocator * aligned_alloc = aws_mem_calloc (aws_default_allocator (), 1 , sizeof (struct aws_allocator ));
189+ * aligned_alloc = s_implicit_aligned_allocator ;
190+ aligned_alloc -> impl = (void * )customized_alignment ;
191+ return aligned_alloc ;
192+ }
193+
194+ void aws_explicit_aligned_allocator_destroy (struct aws_allocator * aligned_alloc ) {
195+ if (!aligned_alloc ) {
196+ return ;
197+ }
198+ aws_mem_release (aws_default_allocator (), aligned_alloc );
169199}
170200
171201void * aws_mem_acquire (struct aws_allocator * allocator , size_t size ) {
0 commit comments