Use aligned allocation for allocator::allocate to support overaligned types.

This commit is contained in:
Ion Gaztañaga
2026-01-10 18:43:38 +01:00
parent 89e70d1608
commit 5069b61f65
5 changed files with 97 additions and 9 deletions

View File

@@ -161,7 +161,7 @@ class allocator
if(size_overflows<sizeof(T)>(count)){ if(size_overflows<sizeof(T)>(count)){
throw bad_alloc(); throw bad_alloc();
} }
return pointer(static_cast<value_type*>(mp_mngr->allocate(count*sizeof(T)))); return pointer(static_cast<value_type*>(mp_mngr->allocate_aligned(count*sizeof(T), boost::container::dtl::alignment_of<T>::value)));
} }
//!Deallocates memory previously allocated. //!Deallocates memory previously allocated.
@@ -242,7 +242,7 @@ class allocator
if(size_overflows<sizeof(T)>(elem_size)){ if(size_overflows<sizeof(T)>(elem_size)){
throw bad_alloc(); throw bad_alloc();
} }
mp_mngr->allocate_many(elem_size*sizeof(T), num_elements, chain); mp_mngr->allocate_many(elem_size*sizeof(T), num_elements, boost::container::dtl::alignment_of<T>::value, chain);
} }
//!Allocates n_elements elements, each one of size elem_sizes[i]in a //!Allocates n_elements elements, each one of size elem_sizes[i]in a
@@ -250,7 +250,7 @@ class allocator
//!of memory. The elements must be deallocated //!of memory. The elements must be deallocated
void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain) void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain)
{ {
mp_mngr->allocate_many(elem_sizes, n_elements, sizeof(T), chain); mp_mngr->allocate_many(elem_sizes, n_elements, sizeof(T), boost::container::dtl::alignment_of<T>::value, chain);
} }
//!Allocates many elements of size elem_size in a contiguous block //!Allocates many elements of size elem_size in a contiguous block

View File

@@ -34,14 +34,14 @@ typedef boost::container::list<test::movable_and_copyable_int, ShmemCopyMoveAllo
typedef allocator<test::copyable_int, managed_shared_memory::segment_manager> ShmemCopyAllocator; typedef allocator<test::copyable_int, managed_shared_memory::segment_manager> ShmemCopyAllocator;
typedef boost::container::list<test::copyable_int, ShmemCopyAllocator> MyCopyList; typedef boost::container::list<test::copyable_int, ShmemCopyAllocator> MyCopyList;
typedef allocator<test::overaligned_copyable_int, managed_shared_memory::segment_manager> ShmemOveralignedAllocator;
typedef boost::container::list<test::overaligned_copyable_int, ShmemOveralignedAllocator> MyOveralignedList;
int main () int main ()
{ {
if(test::list_test<managed_shared_memory, MyList, true>()) if(test::list_test<managed_shared_memory, MyList, true>())
return 1; return 1;
// if(test::list_test<managed_shared_memory, MyVolatileList, true>())
// return 1;
if(test::list_test<managed_shared_memory, MyMoveList, true>()) if(test::list_test<managed_shared_memory, MyMoveList, true>())
return 1; return 1;
@@ -51,6 +51,9 @@ int main ()
if(test::list_test<managed_shared_memory, MyCopyList, true>()) if(test::list_test<managed_shared_memory, MyCopyList, true>())
return 1; return 1;
if(test::list_test<managed_shared_memory, MyOveralignedList, true>())
return 1;
const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_FRONT | test::EMPLACE_BEFORE); const test::EmplaceOptions Options = (test::EmplaceOptions)(test::EMPLACE_BACK | test::EMPLACE_FRONT | test::EMPLACE_BEFORE);
if(!boost::interprocess::test::test_emplace<boost::container::list<test::EmplaceInt>, Options>()) if(!boost::interprocess::test::test_emplace<boost::container::list<test::EmplaceInt>, Options>())

View File

@@ -98,7 +98,7 @@ int list_test (bool copied_allocators_equal = true)
{ {
typedef std::list<int> MyStdList; typedef std::list<int> MyStdList;
typedef typename MyShmList::value_type IntType; typedef typename MyShmList::value_type IntType;
const int Memsize = 128u * 1024u; const int Memsize = 256u * 1024u;
const char *const shMemName = test::get_process_id_name(); const char *const shMemName = test::get_process_id_name();
const int max = 100; const int max = 100;
typedef push_data_function<DoublyLinked> push_data_t; typedef push_data_function<DoublyLinked> push_data_t;

View File

@@ -14,6 +14,7 @@
#include <boost/interprocess/detail/config_begin.hpp> #include <boost/interprocess/detail/config_begin.hpp>
#include <boost/interprocess/detail/workaround.hpp> #include <boost/interprocess/detail/workaround.hpp>
#include <boost/move/utility_core.hpp> #include <boost/move/utility_core.hpp>
#include <boost/container/detail/type_traits.hpp> //alignment_of, aligned_storage
namespace boost { namespace boost {
namespace interprocess { namespace interprocess {
@@ -287,6 +288,84 @@ class non_copymovable_int
int m_int; int m_int;
}; };
class overaligned_copyable_int
{
public:
overaligned_copyable_int()
{
m_d.m_int = 0;
}
explicit overaligned_copyable_int(int a)
{
m_d.m_int = a;
}
overaligned_copyable_int(const overaligned_copyable_int& mmi)
{
m_d.m_int = mmi.m_d.m_int;
}
overaligned_copyable_int & operator= (int i)
{ this->m_d.m_int = i; return *this; }
overaligned_copyable_int & operator=(const overaligned_copyable_int& mmi)
{ m_d.m_int = mmi.m_d.m_int; return *this; }
bool operator ==(const overaligned_copyable_int &mi) const
{ return this->m_d.m_int == mi.m_d.m_int; }
bool operator !=(const overaligned_copyable_int &mi) const
{ return this->m_d.m_int != mi.m_d.m_int; }
bool operator <(const overaligned_copyable_int &mi) const
{ return this->m_d.m_int < mi.m_d.m_int; }
bool operator <=(const overaligned_copyable_int &mi) const
{ return this->m_d.m_int <= mi.m_d.m_int; }
bool operator >=(const overaligned_copyable_int &mi) const
{ return this->m_d.m_int >= mi.m_d.m_int; }
bool operator >(const overaligned_copyable_int &mi) const
{ return this->m_d.m_int > mi.m_d.m_int; }
int get_int() const
{ return m_d.m_int; }
friend bool operator==(const overaligned_copyable_int &l, int r)
{ return l.get_int() == r; }
friend bool operator==(int l, const overaligned_copyable_int &r)
{ return l == r.get_int(); }
private:
union data
{
boost::container::dtl::aligned_storage<sizeof(int), 64>::type aligner;
int m_int;
} m_d;
};
template<class E, class T>
std::basic_ostream<E, T> & operator<<
(std::basic_ostream<E, T> & os, overaligned_copyable_int const & p)
{
os << p.get_int();
return os;
}
template<>
struct is_copyable<overaligned_copyable_int>
{
static const bool value = true;
};
} //namespace test { } //namespace test {
} //namespace interprocess { } //namespace interprocess {
} //namespace boost { } //namespace boost {

View File

@@ -72,7 +72,10 @@ int main()
typedef allocator<test::copyable_int, managed_shared_memory::segment_manager> ShmemCopyAllocator; typedef allocator<test::copyable_int, managed_shared_memory::segment_manager> ShmemCopyAllocator;
typedef boost::container::vector<test::copyable_int, ShmemCopyAllocator> MyCopyVector; typedef boost::container::vector<test::copyable_int, ShmemCopyAllocator> MyCopyVector;
/*
typedef allocator<test::overaligned_copyable_int, managed_shared_memory::segment_manager> ShmemOveralignedAllocator;
typedef boost::container::vector<test::overaligned_copyable_int, ShmemOveralignedAllocator> MyOveralignedVector;
*/
if(test::vector_test<managed_shared_memory, MyVector>()) if(test::vector_test<managed_shared_memory, MyVector>())
return 1; return 1;
@@ -87,7 +90,10 @@ int main()
if(test::vector_test<managed_shared_memory, MyCopyVector>()) if(test::vector_test<managed_shared_memory, MyCopyVector>())
return 1; return 1;
/*
if(test::vector_test<managed_shared_memory, MyOveralignedVector>())
return 1;
*/
if(test_expand_bwd()) if(test_expand_bwd())
return 1; return 1;