Factor alignment code, so it can be reused.

This commit is contained in:
Matthew Parkinson
2020-01-08 15:18:55 +00:00
parent e8e0f60ccf
commit 1fd4ddd23e

View File

@@ -112,6 +112,34 @@ extern "C"
return SNMALLOC_NAME_MANGLE(malloc)(size);
}
inline size_t aligned_size(size_t alignment, size_t size)
{
// Client responsible for checking alignment is not zero
assert(alignment != 0);
// Client responsible for checking alignment is not above SUPERSLAB_SIZE
assert(alignment <= SUPERSLAB_SIZE);
// Client responsible for checking alignment is a power of two
assert(bits::next_pow2(alignment) == alignment);
size = bits::max(size, alignment);
snmalloc::sizeclass_t sc = size_to_sizeclass(size);
if (sc >= NUM_SIZECLASSES)
{
// large allocs are 16M aligned, which is maximum we guarantee
return size;
}
for (; sc < NUM_SIZECLASSES; sc++)
{
size = sizeclass_to_size(sc);
if ((size & (~size + 1)) >= alignment)
{
return size;
}
}
// Give max alignment.
return SUPERSLAB_SIZE;
}
SNMALLOC_EXPORT void*
SNMALLOC_NAME_MANGLE(memalign)(size_t alignment, size_t size)
{
@@ -128,22 +156,7 @@ extern "C"
return nullptr;
}
size = bits::max(size, alignment);
snmalloc::sizeclass_t sc = size_to_sizeclass(size);
if (sc >= NUM_SIZECLASSES)
{
// large allocs are 16M aligned.
return SNMALLOC_NAME_MANGLE(malloc)(size);
}
for (; sc < NUM_SIZECLASSES; sc++)
{
size = sizeclass_to_size(sc);
if ((size & (~size + 1)) >= alignment)
{
return SNMALLOC_NAME_MANGLE(aligned_alloc)(alignment, size);
}
}
return SNMALLOC_NAME_MANGLE(malloc)(SUPERSLAB_SIZE);
return SNMALLOC_NAME_MANGLE(malloc)(aligned_size(alignment, size));
}
SNMALLOC_EXPORT int SNMALLOC_NAME_MANGLE(posix_memalign)(