Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions rclcpp/include/rclcpp/allocator/allocator_common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,39 @@ namespace rclcpp
namespace allocator
{

template<typename T>
using clean_t = std::remove_cv_t<std::remove_reference_t<T>>;

// Primary template: false
template<typename, typename = std::void_t<>>
struct has_get_rcl_allocator : std::false_type {};

// Specialization: true if expression is valid
template<typename T>
struct has_get_rcl_allocator<T,
std::void_t<
decltype(std::declval<clean_t<T> &>().get_rcl_allocator())
>
>
: std::bool_constant<
std::is_same_v<
decltype(std::declval<clean_t<T> &>().get_rcl_allocator()),
rcl_allocator_t
>
>
{};

// Helper variable template
template<typename T>
inline constexpr bool has_get_rcl_allocator_v =
has_get_rcl_allocator<T>::value;

template<typename T, typename Alloc>
using AllocRebind = typename std::allocator_traits<Alloc>::template rebind_traits<T>;

template<typename Alloc>
[[deprecated("Conversion of C++ allocators to C style is not valid, as the size on deallocate"
"can not be determined. This will be remove in future versions of ros.")]]
void * retyped_allocate(size_t size, void * untyped_allocator)
{
auto typed_allocator = static_cast<Alloc *>(untyped_allocator);
Expand All @@ -41,6 +70,8 @@ void * retyped_allocate(size_t size, void * untyped_allocator)
}

template<typename Alloc>
[[deprecated("Conversion of C++ allocators to C style is not valid, as the size on deallocate"
"can not be determined. This will be remove in future versions of ros.")]]
void * retyped_zero_allocate(size_t number_of_elem, size_t size_of_elem, void * untyped_allocator)
{
auto typed_allocator = static_cast<Alloc *>(untyped_allocator);
Expand All @@ -57,6 +88,8 @@ void * retyped_zero_allocate(size_t number_of_elem, size_t size_of_elem, void *
}

template<typename T, typename Alloc>
[[deprecated("Conversion of C++ allocators to C style is not valid, as the size on deallocate"
"can not be determined. This will be remove in future versions of ros.")]]
void retyped_deallocate(void * untyped_pointer, void * untyped_allocator)
{
auto typed_allocator = static_cast<Alloc *>(untyped_allocator);
Expand All @@ -68,6 +101,8 @@ void retyped_deallocate(void * untyped_pointer, void * untyped_allocator)
}

template<typename T, typename Alloc>
[[deprecated("Conversion of C++ allocators to C style is not valid, as the size on deallocate"
"can not be determined. This will be remove in future versions of ros.")]]
void * retyped_reallocate(void * untyped_pointer, size_t size, void * untyped_allocator)
{
auto typed_allocator = static_cast<Alloc *>(untyped_allocator);
Expand All @@ -85,6 +120,9 @@ template<
typename T,
typename Alloc,
typename std::enable_if<!std::is_same<Alloc, std::allocator<void>>::value>::type * = nullptr>
[[deprecated("Conversion of C++ allocators to C style is not valid, as the size on deallocate"
"can not be determined. This will be remove in future versions of ros. To suppress this warning"
"define the method 'rcl_allocator_t get_rcl_allocator()' on your allocator")]]
rcl_allocator_t get_rcl_allocator(Alloc & allocator)
{
rcl_allocator_t rcl_allocator = rcl_get_default_allocator();
Expand Down
23 changes: 21 additions & 2 deletions rclcpp/include/rclcpp/message_memory_strategy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <memory>
#include <stdexcept>

#include "rcl/allocator.h"
#include "rcl/types.h"

#include "rclcpp/allocator/allocator_common.hpp"
Expand Down Expand Up @@ -61,15 +62,33 @@ class MessageMemoryStrategy
message_allocator_ = std::make_shared<MessageAlloc>();
serialized_message_allocator_ = std::make_shared<SerializedMessageAlloc>();
buffer_allocator_ = std::make_shared<BufferAlloc>();
rcutils_allocator_ = allocator::get_rcl_allocator<char, BufferAlloc>(*buffer_allocator_.get());
if constexpr (std::is_same_v<Alloc, std::allocator<void>>) {
rcutils_allocator_ = rcl_get_default_allocator();
} else {
if constexpr (rclcpp::allocator::has_get_rcl_allocator_v<Alloc>) {
rcutils_allocator_ = message_allocator_->get_rcl_allocator();
} else {
rcutils_allocator_ = allocator::get_rcl_allocator<char,
BufferAlloc>(*buffer_allocator_.get());
}
}
}

explicit MessageMemoryStrategy(std::shared_ptr<Alloc> allocator)
{
message_allocator_ = std::make_shared<MessageAlloc>(*allocator.get());
serialized_message_allocator_ = std::make_shared<SerializedMessageAlloc>(*allocator.get());
buffer_allocator_ = std::make_shared<BufferAlloc>(*allocator.get());
rcutils_allocator_ = allocator::get_rcl_allocator<char, BufferAlloc>(*buffer_allocator_.get());
if constexpr (std::is_same_v<Alloc, std::allocator<void>>) {
rcutils_allocator_ = rcl_get_default_allocator();
} else {
if constexpr (rclcpp::allocator::has_get_rcl_allocator_v<Alloc>) {
rcutils_allocator_ = allocator->get_rcl_allocator();
} else {
rcutils_allocator_ = allocator::get_rcl_allocator<char,
BufferAlloc>(*buffer_allocator_.get());
}
}
}

virtual ~MessageMemoryStrategy() = default;
Expand Down
17 changes: 13 additions & 4 deletions rclcpp/include/rclcpp/publisher_options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,20 @@ struct PublisherOptionsWithAllocator : public PublisherOptionsBase
rcl_allocator_t
get_rcl_allocator() const
{
if (!plain_allocator_storage_) {
plain_allocator_storage_ =
std::make_shared<PlainAllocator>(*this->get_allocator());
if constexpr (std::is_same_v<Allocator, std::allocator<void>>) {
return rcl_get_default_allocator();
} else {
if constexpr (rclcpp::allocator::has_get_rcl_allocator_v<Allocator>) {
return get_allocator()->get_rcl_allocator();
} else {
if (!plain_allocator_storage_) {
plain_allocator_storage_ =
std::make_shared<PlainAllocator>(*this->get_allocator());
}

return rclcpp::allocator::get_rcl_allocator<char>(*plain_allocator_storage_);
}
}
return rclcpp::allocator::get_rcl_allocator<char>(*plain_allocator_storage_);
}

// This is a temporal workaround, to make sure that get_allocator()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,11 @@ class AllocatorMemoryStrategy : public memory_strategy::MemoryStrategy

rcl_allocator_t get_allocator() override
{
return rclcpp::allocator::get_rcl_allocator<void *, VoidAlloc>(*allocator_.get());
if constexpr (std::is_same_v<Alloc, std::allocator<void>>) {
return rcl_get_default_allocator();
} else {
return rclcpp::allocator::get_rcl_allocator<void *, VoidAlloc>(*allocator_.get());
}
}

size_t number_of_ready_subscriptions() const override
Expand Down
17 changes: 13 additions & 4 deletions rclcpp/include/rclcpp/subscription_options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,20 @@ struct SubscriptionOptionsWithAllocator : public SubscriptionOptionsBase
rcl_allocator_t
get_rcl_allocator() const
{
if (!plain_allocator_storage_) {
plain_allocator_storage_ =
std::make_shared<PlainAllocator>(*this->get_allocator());
if constexpr (std::is_same_v<Allocator, std::allocator<void>>) {
return rcl_get_default_allocator();
} else {
if constexpr (rclcpp::allocator::has_get_rcl_allocator_v<Allocator>) {
return get_allocator()->get_rcl_allocator();
} else {
if (!plain_allocator_storage_) {
plain_allocator_storage_ =
std::make_shared<PlainAllocator>(*this->get_allocator());
}

return rclcpp::allocator::get_rcl_allocator<char>(*plain_allocator_storage_);
}
}
return rclcpp::allocator::get_rcl_allocator<char>(*plain_allocator_storage_);
}

// This is a temporal workaround, to make sure that get_allocator()
Expand Down
13 changes: 13 additions & 0 deletions rclcpp/test/rclcpp/allocator/test_allocator_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
#include <memory>

#include "rclcpp/allocator/allocator_common.hpp"
#include "rcpputils/compile_warnings.hpp"

TEST(TestAllocatorCommon, retyped_allocate) {
std::allocator<int> allocator;
void * untyped_allocator = &allocator;
RCPPUTILS_DEPRECATION_WARNING_OFF_START
void * allocated_mem =
rclcpp::allocator::retyped_allocate<std::allocator<char>>(1u, untyped_allocator);
// The more natural check here is ASSERT_NE(nullptr, ptr), but clang static
Expand Down Expand Up @@ -49,9 +51,12 @@ TEST(TestAllocatorCommon, retyped_allocate) {
reallocated_mem, untyped_allocator);
};
EXPECT_NO_THROW(code2());

RCPPUTILS_DEPRECATION_WARNING_OFF_STOP
}

TEST(TestAllocatorCommon, retyped_zero_allocate_basic) {
RCPPUTILS_DEPRECATION_WARNING_OFF_START
std::allocator<int> allocator;
void * untyped_allocator = &allocator;
void * allocated_mem =
Expand All @@ -63,9 +68,11 @@ TEST(TestAllocatorCommon, retyped_zero_allocate_basic) {
allocated_mem, untyped_allocator);
};
EXPECT_NO_THROW(code());
RCPPUTILS_DEPRECATION_WARNING_OFF_STOP
}

TEST(TestAllocatorCommon, retyped_zero_allocate) {
RCPPUTILS_DEPRECATION_WARNING_OFF_START
std::allocator<int> allocator;
void * untyped_allocator = &allocator;
void * allocated_mem =
Expand Down Expand Up @@ -96,19 +103,24 @@ TEST(TestAllocatorCommon, retyped_zero_allocate) {
reallocated_mem, untyped_allocator);
};
EXPECT_NO_THROW(code2());
RCPPUTILS_DEPRECATION_WARNING_OFF_STOP
}

TEST(TestAllocatorCommon, get_rcl_allocator) {
RCPPUTILS_DEPRECATION_WARNING_OFF_START
std::allocator<int> allocator;
auto rcl_allocator = rclcpp::allocator::get_rcl_allocator<int>(allocator);
EXPECT_NE(nullptr, rcl_allocator.allocate);
EXPECT_NE(nullptr, rcl_allocator.deallocate);
EXPECT_NE(nullptr, rcl_allocator.reallocate);
EXPECT_NE(nullptr, rcl_allocator.zero_allocate);
// Not testing state as that may or may not be null depending on platform
RCPPUTILS_DEPRECATION_WARNING_OFF_STOP
}

TEST(TestAllocatorCommon, get_void_rcl_allocator) {
RCPPUTILS_DEPRECATION_WARNING_OFF_START

std::allocator<void> allocator;
auto rcl_allocator =
rclcpp::allocator::get_rcl_allocator<void, std::allocator<void>>(allocator);
Expand All @@ -117,4 +129,5 @@ TEST(TestAllocatorCommon, get_void_rcl_allocator) {
EXPECT_NE(nullptr, rcl_allocator.reallocate);
EXPECT_NE(nullptr, rcl_allocator.zero_allocate);
// Not testing state as that may or may not be null depending on platform
RCPPUTILS_DEPRECATION_WARNING_OFF_STOP
}
10 changes: 10 additions & 0 deletions rclcpp/test/rclcpp/test_intra_process_manager_with_allocators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ struct MyAllocator
{
typedef MyAllocator<U> other;
};

rcl_allocator_t get_rcl_allocator()
{
return rcl_get_default_allocator();
}
};

// Explicit specialization for void
Expand Down Expand Up @@ -102,6 +107,11 @@ struct MyAllocator<void>
{
typedef MyAllocator<U> other;
};

rcl_allocator_t get_rcl_allocator()
{
return rcl_get_default_allocator();
}
};

template<typename T, typename U>
Expand Down