Skip to content

PMR support for cetl::unbounded_variant & cetl::pmr::function. - #124

Merged
serges147 merged 46 commits into
mainfrom
sshirokov/84_pmr_fun_ubvar_/valueless
Jun 3, 2024
Merged

serges147 merged 46 commits into
mainfrom
sshirokov/84_pmr_fun_ubvar_/valueless

Conversation

@serges147

@serges147 serges147 commented May 28, 2024

Copy link
Copy Markdown
Contributor
  • Added IsPmr support to cetl::unbounded_variant.
  • Added new cetl::pmr::function (aka std::function but with PMR instead of c++ heap).
  • Added new cetl::pmr::InterfacePtr and its InterfaceFactrory::make_unique
    • based on std::unique_ptr but with custom PMR-based allocator and deleter
    • allows to hide implementation (aka Concrete) type from result InterfacePtr
    • allows to delete destructor from an interface type

@serges147
serges147 marked this pull request as ready for review May 28, 2024 10:31
@serges147
serges147 requested a review from lydia-at-amazon May 28, 2024 10:35

@thirtytwobits thirtytwobits left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also have a cetlpf.hpp in unbounded_variant.hpp we need to remove.

Will use of "cetl/unbounded_variant.hpp" compile if IsPmr is false and no pmr types are included? I would expect this. That is, if we don't require PMR then we should require inclusion of PMR types.

Comment thread cetlvast/include/cetlvast/tracking_memory_resource.hpp
Comment thread include/cetl/pmr/function.hpp Outdated
# include "cetl/cetl.hpp"
#endif

#include "cetl/pf17/cetlpf.hpp"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't include polyfill headers in primary hpp files. The use of any cetlpf.hpp is optional.

//
value_size_ = size_bytes;

return inplace_buffer_;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we not check that size_bytes is <= Footprint and return null if not?

@serges147 serges147 May 29, 2024

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, for non-pmr there is no such thing as "null" storage. Please see static assert at make_handlers - this method is one of the core entry points when it come to creation of a new unbounded variable. So it won't compile (and there is compile test to ensure this, see test_unbounded_variant_footprint_set.cpp).

There are also two other static asserts on attempt to read an arbitrary value (see get_ptr overloads, and corresponding test_unbounded_variant_footprint_get_[non_]const.cpp compile tests).

@serges147

serges147 commented May 29, 2024

Copy link
Copy Markdown
Contributor Author

We also have a cetlpf.hpp in unbounded_variant.hpp we need to remove.

Sorry Scott, but when it comes to "include or not to include" of these two...

  • cetl/pfNN/cetlpf.hpp
  • #ifndef CETL_H_ERASE #include "cetl/cetl.hpp" #endif

... I'm quite confused when which... so far I tried to do as it's in other files.
Also, at cetl/unbounded_variant.hpp I use cetl::byte (which is either std::byte or our cetl::pf17::byte depending on c++ standard), so how can I use cetl::byte without including first cetl/pf17/cetlpf.hpp ?

Will use of "cetl/unbounded_variant.hpp" compile if IsPmr is false and no pmr types are included? I would expect this. That is, if we don't require PMR then we should require inclusion of PMR types.

pmr types are included regardless of IsPmr. I believe it's inevitable (IsPmr is template param, not like some #define). Having said this, You don't pay for what you don't use - all these PMR-specific methods should not be instantiated in the first place (and there are static_assert-s to ensure you don't call them by mistake).

serges147 added 2 commits May 29, 2024 15:23
…erface deleter.

"just in case" b/c `std::unique_ptr` is not allowing invalid casting in the first place,
but I believe such change makes it more explicit (and it was asked for in the first draft review).
@thirtytwobits

thirtytwobits commented May 29, 2024

Copy link
Copy Markdown
Member

Sorry Scott, but when it comes to "include or not to include" of these two...

  • cetl/pfNN/cetlpf.hpp
  • #ifndef CETL_H_ERASE #include "cetl/cetl.hpp" #endif

... I'm quite confused when which... so far I tried to do as it's in other files. Also, at cetl/unbounded_variant.hpp I use cetl::byte (which is either std::byte or our cetl::pf17::byte depending on c++ standard), so how can I use cetl::byte without including first cetl/pf17/cetlpf.hpp ?

The polyfill headers are completely optional in CETL so nothing in CETL should include them, they should include other things from CETL. As for byte, you'll just have to use uint8_t internally. I don't think we're providing byte as part of a public API anywhere in here.

The ideal CETL type only includes cetl.hpp but there are some exceptions to this rule; just never polyfill headers is all. One thing you'll note is the pf headers have a lot of AUTOSAR violations. It's assumed that users of the polyfill are more interested in convenience and portability then pedantry whereas high-criticality code will avoid these headers using the CETL types directly.

@thirtytwobits

Copy link
Copy Markdown
Member

pmr types are included regardless of IsPmr. I believe it's inevitable (IsPmr is template param, not like some #define). Having said this, You don't pay for what you don't use - all these PMR-specific methods should not be instantiated in the first place (and there are static_assert-s to ensure you don't call them by mistake).

If PMR types are always required then we shouldn't also need the "isPMR" parameter. Instead we should just model the default storage as a memory_resource we define locally.

Comment thread include/cetl/pmr/interface_ptr.hpp Outdated
pavel-kirienko
pavel-kirienko previously approved these changes May 31, 2024

@pavel-kirienko pavel-kirienko left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed, it is desirable to eliminate the use of PMR from the deleter, or at least (this may be a better option) provide a new non-PMR deleter that does not have the up-converting constructor and which is used by default while allowing the user to switch to the other one in case of great necessity.

pavel-kirienko
pavel-kirienko previously approved these changes Jun 3, 2024
Comment thread include/cetl/pmr/interface_ptr.hpp
Comment thread include/cetl/pmr/function.hpp Outdated
/// and `reset` (or `reset(Pmr*)`) method to recover from it.
///
template <typename Result, typename... Args, std::size_t Footprint, typename Pmr = void>
inline void swap(cetl::pmr::function<Result(Args...), Footprint, Pmr>& lhs,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inline is redundant for function templates, they are inline by default.

Comment thread include/cetl/pmr/function.hpp Outdated
/// and depending on which stage of swapping the failure happened
/// it could affect (invalidate) either of `lhs` or `rhs` function.
/// Use `valueless_by_exception()` method to check if a function is in such failure state,
/// and `reset` (or `reset(Pmr*)`) method to recover from it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// and `reset` (or `reset(Pmr*)`) method to recover from it.
/// and `reset` (or `reset(Pmr*)`) method (or assign a new value) to recover from it.

Comment thread include/cetl/pmr/function.hpp Outdated
other.handler_ptr_ = get_if<handler_t>(&other.any_handler_);
}

/// True if the function is valueless b/c of an exception.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// True if the function is valueless b/c of an exception.
/// True if the function is valueless b/c of an exception or OOM.

OOM doesn't necessarily cause an exception

Comment thread include/cetl/unbounded_variant.hpp Outdated
return (base::get_value_size() > 0UL) && (nullptr != value_destroyer_);
}

/// True if the variant is valueless b/c of an exception.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// True if the variant is valueless b/c of an exception.
/// True if the variant is valueless b/c of an exception or OOM.

@sonarqubecloud

sonarqubecloud Bot commented Jun 3, 2024

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
88.5% Coverage on New Code (required ≥ 90%)

See analysis details on SonarCloud

@serges147
serges147 merged commit 6510714 into main Jun 3, 2024
@serges147
serges147 deleted the sshirokov/84_pmr_fun_ubvar_/valueless branch June 3, 2024 15:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants