From ad04a677cefc1f0a02fbff0c68409fda6874fdc7 Mon Sep 17 00:00:00 2001 From: Loic Dachary Date: Tue, 2 Dec 2014 00:59:08 +0100 Subject: [PATCH] common: add bufferlist::rebuild_aligned_size_and_memory The function bufferlist::rebuild_aligned checks memory and size alignment with the same variable. It is however useful to separate memory alignment constraints from size alignment constraints. For instance rebuild_aligned could be called to allocate an erasure coded buffer where each 2048 bytes chunk needs to start on a memory address aligned on 32 bytes. Signed-off-by: Loic Dachary (cherry picked from commit 9ade88e8dacc9b96c042bb668f4452447139a544) --- src/common/buffer.cc | 18 +++++++++++------ src/include/buffer.h | 2 ++ src/test/bufferlist.cc | 46 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/src/common/buffer.cc b/src/common/buffer.cc index 9ee2bfedf341..653bd9b748e3 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -1116,11 +1116,17 @@ static simple_spinlock_t buffer_debug_lock = SIMPLE_SPINLOCK_INITIALIZER; } void buffer::list::rebuild_aligned(unsigned align) +{ + rebuild_aligned_size_and_memory(align, align); +} + +void buffer::list::rebuild_aligned_size_and_memory(unsigned align_size, + unsigned align_memory) { std::list::iterator p = _buffers.begin(); while (p != _buffers.end()) { // keep anything that's already align and sized aligned - if (p->is_aligned(align) && p->is_n_align_sized(align)) { + if (p->is_aligned(align_memory) && p->is_n_align_sized(align_size)) { /*cout << " segment " << (void*)p->c_str() << " offset " << ((unsigned long)p->c_str() & (align - 1)) << " length " << p->length() @@ -1144,11 +1150,11 @@ void buffer::list::rebuild_aligned(unsigned align) unaligned.push_back(*p); _buffers.erase(p++); } while (p != _buffers.end() && - (!p->is_aligned(align) || - !p->is_n_align_sized(align) || - (offset & (align-1)))); - if (!(unaligned.is_contiguous() && unaligned._buffers.front().is_aligned(align))) { - ptr nb(buffer::create_aligned(unaligned._len, align)); + (!p->is_aligned(align_memory) || + !p->is_n_align_sized(align_size) || + (offset % align_size))); + if (!(unaligned.is_contiguous() && unaligned._buffers.front().is_aligned(align_memory))) { + ptr nb(buffer::create_aligned(unaligned._len, align_memory)); unaligned.rebuild(nb); } _buffers.insert(p, unaligned._buffers.front()); diff --git a/src/include/buffer.h b/src/include/buffer.h index 0ce133a29641..da19cf95a519 100644 --- a/src/include/buffer.h +++ b/src/include/buffer.h @@ -393,6 +393,8 @@ public: void rebuild(); void rebuild(ptr& nb); void rebuild_aligned(unsigned align); + void rebuild_aligned_size_and_memory(unsigned align_size, + unsigned align_memory); void rebuild_page_aligned(); // sort-of-like-assignment-op diff --git a/src/test/bufferlist.cc b/src/test/bufferlist.cc index da4d33ff2b4d..170bf7b465a0 100644 --- a/src/test/bufferlist.cc +++ b/src/test/bufferlist.cc @@ -1212,6 +1212,52 @@ TEST(BufferList, is_n_page_sized) { } } +TEST(BufferList, rebuild_aligned_size_and_memory) { + const unsigned SIMD_ALIGN = 32; + const unsigned BUFFER_SIZE = 67; + + bufferlist bl; + // These two must be concatenated into one memory + size aligned + // bufferptr + { + bufferptr ptr(buffer::create_aligned(2, SIMD_ALIGN)); + ptr.set_offset(1); + ptr.set_length(1); + bl.append(ptr); + } + { + bufferptr ptr(buffer::create_aligned(BUFFER_SIZE - 1, SIMD_ALIGN)); + bl.append(ptr); + } + // This one must be left alone + { + bufferptr ptr(buffer::create_aligned(BUFFER_SIZE, SIMD_ALIGN)); + bl.append(ptr); + } + // These two must be concatenated into one memory + size aligned + // bufferptr + { + bufferptr ptr(buffer::create_aligned(2, SIMD_ALIGN)); + ptr.set_offset(1); + ptr.set_length(1); + bl.append(ptr); + } + { + bufferptr ptr(buffer::create_aligned(BUFFER_SIZE - 1, SIMD_ALIGN)); + bl.append(ptr); + } + EXPECT_FALSE(bl.is_aligned(SIMD_ALIGN)); + EXPECT_FALSE(bl.is_n_align_sized(BUFFER_SIZE)); + EXPECT_EQ(BUFFER_SIZE * 3, bl.length()); + EXPECT_FALSE(bl.buffers().front().is_aligned(SIMD_ALIGN)); + EXPECT_FALSE(bl.buffers().front().is_n_align_sized(BUFFER_SIZE)); + EXPECT_EQ(5U, bl.buffers().size()); + bl.rebuild_aligned_size_and_memory(BUFFER_SIZE, SIMD_ALIGN); + EXPECT_TRUE(bl.is_aligned(SIMD_ALIGN)); + EXPECT_TRUE(bl.is_n_align_sized(BUFFER_SIZE)); + EXPECT_EQ(3U, bl.buffers().size()); +} + TEST(BufferList, is_zero) { { bufferlist bl; -- 2.47.3