Commit 0d92b69f authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Let AlignedSysAllocator consider the type's alignment

Summary: [Folly] Let AlignedSysAllocator consider the natural or specified alignment of the type for which memory is being allocated, rather than only considering a constant or fixed alignment.

Reviewed By: nbronson

Differential Revision: D19174932

fbshipit-source-id: e8ed0fbaf30d285cadd061d0fe5d69fcbb16f9e2
parent 4762e080
...@@ -403,8 +403,8 @@ class DefaultAlign { ...@@ -403,8 +403,8 @@ class DefaultAlign {
assert(!(align_ < sizeof(void*)) && bool("bad align: too small")); assert(!(align_ < sizeof(void*)) && bool("bad align: too small"));
assert(!(align_ & (align_ - 1)) && bool("bad align: not power-of-two")); assert(!(align_ & (align_ - 1)) && bool("bad align: not power-of-two"));
} }
std::size_t operator()() const noexcept { std::size_t operator()(std::size_t align) const noexcept {
return align_; return align_ < align ? align : align_;
} }
friend bool operator==(Self const& a, Self const& b) noexcept { friend bool operator==(Self const& a, Self const& b) noexcept {
...@@ -423,8 +423,8 @@ class FixedAlign { ...@@ -423,8 +423,8 @@ class FixedAlign {
using Self = FixedAlign<Align>; using Self = FixedAlign<Align>;
public: public:
constexpr std::size_t operator()() const noexcept { constexpr std::size_t operator()(std::size_t align) const noexcept {
return Align; return Align < align ? align : Align;
} }
friend bool operator==(Self const&, Self const&) noexcept { friend bool operator==(Self const&, Self const&) noexcept {
...@@ -442,7 +442,8 @@ class FixedAlign { ...@@ -442,7 +442,8 @@ class FixedAlign {
* aligned_free. * aligned_free.
* *
* Accepts a policy parameter for providing the alignment, which must: * Accepts a policy parameter for providing the alignment, which must:
* * be invocable as std::size_t() noexcept, returning the alignment * * be invocable as std::size_t(std::size_t) noexcept
* * taking the type alignment and returning the allocation alignment
* * be noexcept-copy-constructible * * be noexcept-copy-constructible
* * have noexcept operator== * * have noexcept operator==
* * have noexcept operator!= * * have noexcept operator!=
...@@ -464,7 +465,9 @@ class AlignedSysAllocator : private Align { ...@@ -464,7 +465,9 @@ class AlignedSysAllocator : private Align {
public: public:
static_assert(std::is_nothrow_copy_constructible<Align>::value, ""); static_assert(std::is_nothrow_copy_constructible<Align>::value, "");
static_assert(is_nothrow_invocable_r<std::size_t, Align>::value, ""); static_assert(
is_nothrow_invocable_r<std::size_t, Align, std::size_t>::value,
"");
using value_type = T; using value_type = T;
...@@ -481,7 +484,8 @@ class AlignedSysAllocator : private Align { ...@@ -481,7 +484,8 @@ class AlignedSysAllocator : private Align {
T* allocate(size_t count) { T* allocate(size_t count) {
using lifted = typename detail::lift_void_to_char<T>::type; using lifted = typename detail::lift_void_to_char<T>::type;
auto const p = aligned_malloc(sizeof(lifted) * count, align()()); auto const a = align()(alignof(lifted));
auto const p = aligned_malloc(sizeof(lifted) * count, a);
if (!p) { if (!p) {
if (FOLLY_UNLIKELY(errno != ENOMEM)) { if (FOLLY_UNLIKELY(errno != ENOMEM)) {
std::terminate(); std::terminate();
......
...@@ -138,6 +138,18 @@ TEST(AlignedSysAllocator, allocate_unique_fixed) { ...@@ -138,6 +138,18 @@ TEST(AlignedSysAllocator, allocate_unique_fixed) {
EXPECT_EQ(0, std::uintptr_t(ptr.get()) % 1024); EXPECT_EQ(0, std::uintptr_t(ptr.get()) % 1024);
} }
TEST(AlignedSysAllocator, undersized_fixed) {
constexpr auto align = has_extended_alignment ? 1024 : max_align_v;
struct alignas(align) Big {
float value;
};
using Alloc = AlignedSysAllocator<Big, FixedAlign<sizeof(void*)>>;
Alloc const alloc;
auto ptr = allocate_unique<Big>(alloc, Big{3.});
EXPECT_EQ(3., ptr->value);
EXPECT_EQ(0, std::uintptr_t(ptr.get()) % align);
}
TEST(AlignedSysAllocator, vector_fixed) { TEST(AlignedSysAllocator, vector_fixed) {
using Alloc = AlignedSysAllocator<float, FixedAlign<1024>>; using Alloc = AlignedSysAllocator<float, FixedAlign<1024>>;
Alloc const alloc; Alloc const alloc;
...@@ -174,6 +186,18 @@ TEST(AlignedSysAllocator, allocate_unique_default) { ...@@ -174,6 +186,18 @@ TEST(AlignedSysAllocator, allocate_unique_default) {
EXPECT_EQ(0, std::uintptr_t(ptr.get()) % 1024); EXPECT_EQ(0, std::uintptr_t(ptr.get()) % 1024);
} }
TEST(AlignedSysAllocator, undersized_default) {
constexpr auto align = has_extended_alignment ? 1024 : max_align_v;
struct alignas(align) Big {
float value;
};
using Alloc = AlignedSysAllocator<Big, DefaultAlign>;
Alloc const alloc(sizeof(void*));
auto ptr = allocate_unique<Big>(alloc, Big{3.});
EXPECT_EQ(3., ptr->value);
EXPECT_EQ(0, std::uintptr_t(ptr.get()) % align);
}
TEST(AlignedSysAllocator, vector_default) { TEST(AlignedSysAllocator, vector_default) {
using Alloc = AlignedSysAllocator<float>; using Alloc = AlignedSysAllocator<float>;
Alloc const alloc(1024); Alloc const alloc(1024);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment