-
Notifications
You must be signed in to change notification settings - Fork 160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
aws_customized_aligned_allocator #1147
base: main
Are you sure you want to change the base?
Changes from 3 commits
dd4e827
c4d45ea
9e81964
f888d22
be99adf
b91b75b
095b34f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -34,6 +34,11 @@ bool aws_allocator_is_valid(const struct aws_allocator *alloc) { | |||||
return alloc && AWS_OBJECT_PTR_IS_READABLE(alloc) && alloc->mem_acquire && alloc->mem_release; | ||||||
} | ||||||
|
||||||
struct aws_aligned_allocator_impl { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use "explicit" or "custom" in this struct name (match the public function name) Otherwise, one would assume this is for Which is extra confusing because both share the s_aligned_malloc() call, and it's tough to explain "you can tell that it's NOT the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OR make it so that both then in s_aligned_malloc(), you can simply branch on whether or not There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Go with @DmitriyMusatkin 's suggestion to remove the whole impl, and use the point address to store the size_t for the alignment. |
||||||
struct aws_allocator *allocator; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's really confusing to see code that's like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh wait, reading more code ... this allocator is only used to create this one single aws_aligned_allocator_impl struct? It's not actually used for the underlying allocations, those come from posix_memalign(). Maybe just don't even bother passing an allocator here, just use aws_default_allocator() to create the impl. That's what aws_mem_tracer_new() does. When the user passes an allocator, there's a general understanding that THIS is the allocator that will be used for further allocations. But that's not the case here. If aligned-allocations leaks, the passed-in allocator has no idea, it wasn't involved at all. |
||||||
size_t alignment_size; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. trivial:
Suggested change
|
||||||
}; | ||||||
|
||||||
static void *s_aligned_malloc(struct aws_allocator *allocator, size_t size) { | ||||||
(void)allocator; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. probably not needed anymore? |
||||||
/* larger allocations should be aligned so that AVX and friends can avoid | ||||||
|
@@ -46,9 +51,15 @@ static void *s_aligned_malloc(struct aws_allocator *allocator, size_t size) { | |||||
* 8 byte alignment for <= page allocations on 32 bit systems | ||||||
* | ||||||
* We use PAGE_SIZE as the boundary because we are not aware of any allocations of | ||||||
* this size or greater that are not data buffers | ||||||
* this size or greater that are not data buffers. | ||||||
* | ||||||
* Unless there is a customized alignment size. | ||||||
*/ | ||||||
const size_t alignment = sizeof(void *) * (size > (size_t)PAGE_SIZE ? 8 : 2); | ||||||
size_t alignment = sizeof(void *) * (size > (size_t)PAGE_SIZE ? 8 : 2); | ||||||
if (allocator->impl) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. allocator will not have impl if its aligned by default? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. dumb idea, but maybe just let impl be the actual alignment (i.e. just cast impl pointer to size_t and back) instead of allocating another chunk of mem for it? |
||||||
struct aws_aligned_allocator_impl *impl = allocator->impl; | ||||||
alignment = impl->alignment_size; | ||||||
} | ||||||
TingDaoK marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
#if !defined(_WIN32) | ||||||
void *result = NULL; | ||||||
int err = posix_memalign(&result, alignment, size); | ||||||
|
@@ -168,6 +179,49 @@ struct aws_allocator *aws_aligned_allocator(void) { | |||||
return &aligned_allocator; | ||||||
} | ||||||
|
||||||
struct aws_allocator *aws_customized_aligned_allocator_new( | ||||||
struct aws_allocator *allocator, | ||||||
size_t customized_alignment) { | ||||||
if ((customized_alignment & (customized_alignment - 1)) != 0 || customized_alignment % sizeof(void *) != 0) { | ||||||
/** | ||||||
* the alignment must be a power of two and a multiple of sizeof(void *) | ||||||
*/ | ||||||
aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); | ||||||
return NULL; | ||||||
} | ||||||
|
||||||
struct aws_aligned_allocator_impl *aligned_alloc_impl = NULL; | ||||||
struct aws_allocator *aligned_alloc = NULL; | ||||||
aws_mem_acquire_many( | ||||||
allocator, | ||||||
2, | ||||||
&aligned_alloc_impl, | ||||||
sizeof(struct aws_aligned_allocator_impl), | ||||||
&aligned_alloc, | ||||||
sizeof(struct aws_allocator)); | ||||||
|
||||||
AWS_ZERO_STRUCT(*aligned_alloc_impl); | ||||||
AWS_ZERO_STRUCT(*aligned_alloc); | ||||||
/* copy the template vtable */ | ||||||
*aligned_alloc = aligned_allocator; | ||||||
aligned_alloc->impl = aligned_alloc_impl; | ||||||
aligned_alloc_impl->alignment_size = customized_alignment; | ||||||
aligned_alloc_impl->allocator = allocator; | ||||||
return aligned_alloc; | ||||||
} | ||||||
|
||||||
void aws_customized_aligned_allocator_destroy(struct aws_allocator *aligned_alloc) { | ||||||
if (!aligned_alloc) { | ||||||
return; | ||||||
} | ||||||
struct aws_aligned_allocator_impl *impl = aligned_alloc->impl; | ||||||
if (!impl) { | ||||||
return; | ||||||
} | ||||||
struct aws_allocator *allocator = impl->allocator; | ||||||
aws_mem_release(allocator, impl); | ||||||
} | ||||||
|
||||||
void *aws_mem_acquire(struct aws_allocator *allocator, size_t size) { | ||||||
AWS_FATAL_PRECONDITION(allocator != NULL); | ||||||
AWS_FATAL_PRECONDITION(allocator->mem_acquire != NULL); | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe just aws_custom_alignment_allocator_new?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume it's named this way because the nice simple name
aws_aligned_allocator()
is already taken, but that one automagically determines the alignment, and it differs based on allocation size.Move these new functions to be right next to the existing
aws_aligned_allocator()
(instead of the end of the file) so that someone searching "align" is more likely to see both options and pick the right one.I like "explicit" more than "custom". "custom" sounds like "you can do whatever you want like via a callback" while "explicit" sounds to me like "we simply use this 1 number you give us".
I'd suggest
aws_explicit_aligned_allocator()
(sounds like the pre-existing allocator) oraws_explicit_alignment_allocator()
(nicer sounding gramatically)