diff --git a/doc/design/relocatable_pointer.md b/doc/design/relocatable_pointer.md index 7c3560456d..005e36619e 100644 --- a/doc/design/relocatable_pointer.md +++ b/doc/design/relocatable_pointer.md @@ -7,7 +7,7 @@ even to the shared memory), i.e. the pointer is invalid. In this case, different relocatable pointers must be used. Depending on the shared memory setup and the relationship between pointer and pointee, there are different use cases which we need to cover. -Both relative_ptr and relocatable_ptr are template pointer classes that try to retain much of the normal pointer +Both RelativePointer and RelocatablePointer are template pointer classes that try to retain much of the normal pointer syntax where possible while still being valid across address space boundaries. This means that operations like assignment, dereferencing, comparison and so on work similar to raw pointers. They do not possess reference counting semantics in this implementation, but extensions for this functionality are possible. @@ -44,7 +44,7 @@ This is why storing a raw pointer to X will not be sufficient, the value c1 of p However, storing the difference between the location of p and X will work since it is an invariant in both address spaces. -Thus, instead of using a raw pointer p, we just use a relocatable pointer relocatable_ptr pointing to X. This pointer +Thus, instead of using a raw pointer p, we just use a relocatable pointer RelocatablePointer pointing to X. This pointer can then be dereferenced in both address spaces and will point to X. Note that if we only use relocatable pointers in this way in complex data structures that rely on pointers (such as @@ -60,16 +60,16 @@ segment* (e.g. as members of objects that reside in this segment or via emplacem segment). default construct a logical nullptr -+ `relocatable_ptr p;` ++ `RelocatablePointer p;` construct relocatable pointing to X -+ `relocatable_ptr p(&X);` ++ `RelocatablePointer p(&X);` assign relocatable to point to X + `p = &X;` ### Operations -Most operations for raw pointers also work for relocatable pointers. In particular, a relocatable_ptr is compatible +Most operations for raw pointers also work for relocatable pointers. In particular, a RelocatablePointer is compatible with a raw pointer T* in many cases, such as assignment, to provide seamless integration and convenient syntax. comparison with raw pointers @@ -151,19 +151,19 @@ Assume we have an object X of type T in shared memory. Then we can construct rel registered segments*. default construct a logical nullptr -+ `relative_ptr rp;` ++ `RelativePointer rp;` construct relative pointer pointing to X (provided the segment containing X was registered) -+ `relative_ptr rp(&X);` ++ `RelativePointer rp(&X);` assign relative pointer to point to X + `rp = &X;` copy construction -+ `relative_ptr rp2(rp);` ++ `RelativePointer rp2(rp);` copy assignment -+ `relative_ptr rp2 = rp;` ++ `RelativePointer rp2 = rp;` ### Operations @@ -197,19 +197,19 @@ the operations incur slightly more overhead compared to relocatable pointers. ## Atomic usage -There is a technical problem using both relocatable_ptr and relative_ptr as a type in a std::atomic. This is essentially +There is a technical problem using both RelocatablePointer and RelativePointer as a type in a std::atomic. This is essentially impossible as an atomic requires its type to be copyable/movable (to be loaded) but on the other hand, this copy constructor must be trivial, i.e. performable with a shallow memcpy. Therefore, the types used in atomic cannot implement -custom copy/move. This is not possible for relocatable_ptr and relative_ptr as both require operations performed +custom copy/move. This is not possible for RelocatablePointer and RelativePointer as both require operations performed during copying, which cannot be done by a simple shallow copy. -To support the use case of an atomic relocatable pointer, the template atomic_relocatable_ptr is provided. It is a -basic version of a relocatable_ptr, which lacks some of its move functionality and other operations. However, its -existing operations behave like relocatable_ptr but in an atomic way (but also incur additional overhead caused by +To support the use case of an atomic relocatable pointer, the template AtomicRelocatablePointer is provided. It is a +basic version of a RelocatablePointer, which lacks some of its move functionality and other operations. However, its +existing operations behave like RelocatablePointer but in an atomic way (but also incur additional overhead caused by atomic loads and stores). Therefore, this object can be used concurrently by multiple threads, in contrast to -relative_ptr and relocatable_ptr. This atomic version also utilizes lock free atomic operations internally (when +RelativePointer and RelocatablePointer. This atomic version also utilizes lock free atomic operations internally (when available on the target architecture) as the data to be stored is just a 64 bit word. -Note that this cannot be done as easily for relative_ptr as it requires more than 64 bit to store its internal +Note that this cannot be done as easily for RelativePointer as it requires more than 64 bit to store its internal information. A construction where atomicity is guaranteed via locking could be provided in the future. diff --git a/iceoryx_utils/include/iceoryx_utils/internal/relocatable_pointer/atomic_relocatable_ptr.hpp b/iceoryx_utils/include/iceoryx_utils/internal/relocatable_pointer/atomic_relocatable_ptr.hpp index c556e3c92d..01613c418b 100644 --- a/iceoryx_utils/include/iceoryx_utils/internal/relocatable_pointer/atomic_relocatable_ptr.hpp +++ b/iceoryx_utils/include/iceoryx_utils/internal/relocatable_pointer/atomic_relocatable_ptr.hpp @@ -31,28 +31,28 @@ namespace rp /// internally used offset must be an invariant different across adress spaces. Rationale: the default /// RelocatablePointer cannot be used in an atomic since the copy ctor is nontrivial. template -class atomic_relocatable_ptr +class AtomicRelocatablePointer { public: using offset_t = std::ptrdiff_t; static constexpr offset_t NULL_POINTER_OFFSET = std::numeric_limits::max(); - /// @brief creates an atomic_relocatable_ptr pointing to the same pointee as ptr + /// @brief creates an AtomicRelocatablePointer pointing to the same pointee as ptr /// @param[in] ptr the pointer whose pointee shall be the same for this - atomic_relocatable_ptr(const T* ptr = nullptr) noexcept; + AtomicRelocatablePointer(const T* ptr = nullptr) noexcept; /// @todo: can be implemented when needed, note that the offset must be recomputed during the move/copy - atomic_relocatable_ptr(const atomic_relocatable_ptr&) = delete; - atomic_relocatable_ptr& operator=(const atomic_relocatable_ptr& other) = delete; - atomic_relocatable_ptr(atomic_relocatable_ptr&& other) = delete; - atomic_relocatable_ptr& operator=(atomic_relocatable_ptr&& other) = delete; + AtomicRelocatablePointer(const AtomicRelocatablePointer&) = delete; + AtomicRelocatablePointer& operator=(const AtomicRelocatablePointer& other) = delete; + AtomicRelocatablePointer(AtomicRelocatablePointer&& other) = delete; + AtomicRelocatablePointer& operator=(AtomicRelocatablePointer&& other) = delete; /// @note minimal set of required operators, can be extended later - /// @brief assign atomic_relocatable_ptr to point to the same pointee as ptr + /// @brief assign AtomicRelocatablePointer to point to the same pointee as ptr /// @param[in] ptr the pointer whose pointee shall be the same for this /// @return reference to self - atomic_relocatable_ptr& operator=(const T* ptr) noexcept; + AtomicRelocatablePointer& operator=(const T* ptr) noexcept; /// @brief access to the underlying object in shared memory /// @return a pointer to the underlying object @@ -62,7 +62,7 @@ class atomic_relocatable_ptr /// @return a reference to the pointee T& operator*() const noexcept; - /// @brief converts the atomic_relocatable_ptr to a pointer of type of the underlying object + /// @brief converts the AtomicRelocatablePointer to a pointer of type of the underlying object /// @return a pointer of type T pointing to the underlying object operator T*() const noexcept; diff --git a/iceoryx_utils/include/iceoryx_utils/internal/relocatable_pointer/atomic_relocatable_ptr.inl b/iceoryx_utils/include/iceoryx_utils/internal/relocatable_pointer/atomic_relocatable_ptr.inl index 00e8560a1d..e174a4329b 100644 --- a/iceoryx_utils/include/iceoryx_utils/internal/relocatable_pointer/atomic_relocatable_ptr.inl +++ b/iceoryx_utils/include/iceoryx_utils/internal/relocatable_pointer/atomic_relocatable_ptr.inl @@ -25,39 +25,39 @@ namespace iox namespace rp { template -inline atomic_relocatable_ptr::atomic_relocatable_ptr(const T* ptr) noexcept +inline AtomicRelocatablePointer::AtomicRelocatablePointer(const T* ptr) noexcept : m_offset(computeOffset(ptr)) { } template -inline atomic_relocatable_ptr& atomic_relocatable_ptr::operator=(const T* ptr) noexcept +inline AtomicRelocatablePointer& AtomicRelocatablePointer::operator=(const T* ptr) noexcept { m_offset.store(computeOffset(ptr), std::memory_order_relaxed); return *this; } template -inline T* atomic_relocatable_ptr::operator->() const noexcept +inline T* AtomicRelocatablePointer::operator->() const noexcept { return computeRawPtr(); } template -inline T& atomic_relocatable_ptr::operator*() const noexcept +inline T& AtomicRelocatablePointer::operator*() const noexcept { return *computeRawPtr(); } template -inline atomic_relocatable_ptr::operator T*() const noexcept +inline AtomicRelocatablePointer::operator T*() const noexcept { return computeRawPtr(); } template -inline T* atomic_relocatable_ptr::computeRawPtr() const noexcept +inline T* AtomicRelocatablePointer::computeRawPtr() const noexcept { auto offset = m_offset.load(std::memory_order_relaxed); if (offset == NULL_POINTER_OFFSET) @@ -69,8 +69,8 @@ inline T* atomic_relocatable_ptr::computeRawPtr() const noexcept } template -inline typename atomic_relocatable_ptr::offset_t -atomic_relocatable_ptr::computeOffset(const void* ptr) const noexcept +inline typename AtomicRelocatablePointer::offset_t +AtomicRelocatablePointer::computeOffset(const void* ptr) const noexcept { if (ptr == nullptr) { diff --git a/iceoryx_utils/include/iceoryx_utils/internal/relocatable_pointer/pointer_repository.hpp b/iceoryx_utils/include/iceoryx_utils/internal/relocatable_pointer/pointer_repository.hpp index 9e335dc073..1f9f57d52b 100644 --- a/iceoryx_utils/include/iceoryx_utils/internal/relocatable_pointer/pointer_repository.hpp +++ b/iceoryx_utils/include/iceoryx_utils/internal/relocatable_pointer/pointer_repository.hpp @@ -73,7 +73,8 @@ class PointerRepository /// @attention the relative pointers corresponding to this id become unsafe to use bool unregisterPtr(id_t id) noexcept; - /// @brief unregisters all ids and also invalidates all relative pointers + /// @brief unregisters all ids + /// @attention the relative pointers corresponding to this id become unsafe to use void unregisterAll() noexcept; /// @brief gets the base pointer, i.e. the starting address, associated with id diff --git a/iceoryx_utils/test/moduletests/test_atomic_relocatable_ptr.cpp b/iceoryx_utils/test/moduletests/test_atomic_relocatable_ptr.cpp index cbb99b7f8d..0e16a77850 100644 --- a/iceoryx_utils/test/moduletests/test_atomic_relocatable_ptr.cpp +++ b/iceoryx_utils/test/moduletests/test_atomic_relocatable_ptr.cpp @@ -69,7 +69,7 @@ class Foo }; template -using Ptr = iox::rp::atomic_relocatable_ptr; +using Ptr = iox::rp::AtomicRelocatablePointer; class AtomicRelocatablePointer_test : public Test {