Skip to content

Commit

Permalink
iox-eclipse-iceoryx#1391 Move 'SoFi' to new location
Browse files Browse the repository at this point in the history
  • Loading branch information
elBoberido committed Dec 22, 2023
1 parent fd1f97b commit 514f0b2
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 136 deletions.
3 changes: 3 additions & 0 deletions .clang-tidy-diff-scans.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@

./iceoryx_hoofs/posix/**/*

./iceoryx_hoofs/concurrent/**/*
./iceoryx_hoofs/test/moduletests/test_concurrent_*

./iceoryx_hoofs/container/**/*
./iceoryx_hoofs/test/moduletests/test_container_*

Expand Down
6 changes: 3 additions & 3 deletions iceoryx_hoofs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@ The module structure is a logical grouping. It is replicated for `concurrent` an
|`SpscFifo` | i | Single producer, single consumer lock-free FiFo |
|`LockfreeQueue` | | Multi producer, multi consumer lock-free FiFo with ringbuffer like overflow handling |
|`MpmcLoFFLi` | i | Lock-free LIFO based index manager (lock-free free list). One building block of our memory manager. After construction it contains the indices {0 ... n} which you can acquire and release. |
|`SoFi` | i | Single producer, single consumer lock-free safely overflowing FiFo (SoFi). |
|`SpscSofi` | i | Single producer, single consumer lock-free safely overflowing FiFo (SpscSofi). |
|`ResizeableLockFreeQueue` | | Resizeable variant of the `LockfreeQueue` |
|`stack` | | Stack implementation with simple push/pop interface. |
|`VariantQueue` | | A queue which wraps multiple variants of Queues (FiFo, SoFi, ResizeableLockFreeQueue) - will be moved to `iceoryx_posh` - |
|`VariantQueue` | | A queue which wraps multiple variants of Queues (SpscFifo, SpscSofi, ResizeableLockFreeQueue) - will be moved to `iceoryx_posh` - |

#### Attribute overview of the available buffers

Expand All @@ -114,7 +114,7 @@ The module structure is a logical grouping. It is replicated for `concurrent` an
|`SpscFifo` | Yes | Yes | Yes | 1:1 | Yes | Copyable | FIFO Data transfer |
|`LockfreeQueue` | Yes | Yes | Yes | n:m | Yes | Copyable or Movable | lock-free transfer of arbitrary data between multiple contexts in FIFO order with overflow handling (ringbuffer) |
|`MpmcLoFFLi` | Yes | Yes | Yes | n:m | Yes | int32 | manage memory access, LIFO order |
|`SoFi` | Yes | Yes | Yes | 1:1 | Yes | Trivially Copyable | lock-free transfer of small data (e.g. pointers) between two contexts in FIFO order with overflow handling (ringbuffer) |
|`SpscSofi` | Yes | Yes | Yes | 1:1 | Yes | Trivially Copyable | lock-free transfer of small data (e.g. pointers) between two contexts in FIFO order with overflow handling (ringbuffer) |
|`ResizeableLockFreeQueue` | Yes | Yes | Yes | n:m | Yes | Copyable or Movable | Resizeable variant of the `LockfreeQueue` |
|`stack` | Yes | No | - | - | Yes | None | Stack for a single-threaded application |

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
#ifndef IOX_HOOFS_CONCURRENT_SOFI_HPP
#define IOX_HOOFS_CONCURRENT_SOFI_HPP

#ifndef IOX_HOOFS_CONCURRENT_BUFFER_SPSC_SOFI_HPP
#define IOX_HOOFS_CONCURRENT_BUFFER_SPSC_SOFI_HPP

#include "iceoryx_platform/platform_correction.hpp"
#include "iox/type_traits.hpp"
Expand All @@ -31,49 +32,50 @@ namespace concurrent
{
/// @brief
/// Thread safe producer and consumer queue with a safe overflowing behavior.
/// SoFi is designed in a FIFO Manner but prevents data loss when pushing into
/// a full SoFi. When SoFi is full and a Sender tries to push, the data at the
/// current read position will be returned. SoFi is a Thread safe without using
/// SpscSofi is designed in a FIFO Manner but prevents data loss when pushing into
/// a full SpscSofi. When SpscSofi is full and a Sender tries to push, the data at the
/// current read position will be returned. SpscSofi is threadsafe without using
/// locks. When the buffer is filled, new data is written starting at the
/// beginning of the buffer and overwriting the old.The SoFi is especially
/// beginning of the buffer and overwriting the old.The SpscSofi is especially
/// designed to provide fixed capacity storage. When its capacity is exhausted,
/// newly inserted elements will cause elements either at the beginning
/// to be overwritten.The SoFi only allocates memory when
/// to be overwritten.The SpscSofi only allocates memory when
/// created , capacity can be is adjusted explicitly.
///
/// @param[in] ValueType DataType to be stored, must be trivially copyable
/// @param[in] CapacityValue Capacity of the SoFi
/// @param[in] CapacityValue Capacity of the SpscSofi
template <class ValueType, uint64_t CapacityValue>
class SoFi
class SpscSofi
{
static_assert(std::is_trivially_copyable<ValueType>::value, "SoFi can handle only trivially copyable data types");
static_assert(std::is_trivially_copyable<ValueType>::value,
"SpscSofi can handle only trivially copyable data types");
/// @brief Check if Atomic integer is lockfree on platform
/// ATOMIC_INT_LOCK_FREE = 2 - is always lockfree
/// ATOMIC_INT_LOCK_FREE = 1 - is sometimes lockfree
/// ATOMIC_INT_LOCK_FREE = 0 - is never lockfree
static_assert(2 <= ATOMIC_INT_LOCK_FREE, "SoFi is not able to run lock free on this data type");
static_assert(2 <= ATOMIC_INT_LOCK_FREE, "SpscSofi is not able to run lock free on this data type");

/// @brief Internal size needs to be bigger than the size desirred by the user
/// This is because of buffer empty detection and overflow handling
static constexpr uint32_t INTERNAL_SIZE_ADD_ON = 1;

/// @brief This is the resulting internal size on creation
static constexpr uint32_t INTERNAL_SOFI_SIZE = CapacityValue + INTERNAL_SIZE_ADD_ON;
static constexpr uint32_t INTERNAL_SPSC_SOFI_SIZE = CapacityValue + INTERNAL_SIZE_ADD_ON;

public:
/// @brief default constructor which constructs an empty sofi
SoFi() noexcept = default;
SpscSofi() noexcept = default;

/// @brief pushs an element into sofi. if sofi is full the oldest data will be
/// @brief pushs an element into SpscSofi. if SpscSofi is full the oldest data will be
/// returned and the pushed element is stored in its place instead.
/// @param[in] valueIn value which should be stored
/// @param[out] valueOut if sofi is overflowing the value of the overridden value
/// @param[out] valueOut if SpscSofi is overflowing the value of the overridden value
/// is stored here
/// @concurrent restricted thread safe: single pop, single push no
/// push calls from multiple contexts
/// @return return true if push was sucessfull else false.
/// @code
/// (initial situation, SOFI is FULL)
/// (initial situation, SpscSofi is FULL)
/// Start|-----A-------|
/// |-----B-------|
/// |-----C-------|
Expand All @@ -89,9 +91,9 @@ class SoFi
///
/// ###################################################################
///
/// (if SOFI is not FULL , calling push() add new data)
/// (if SpscSofi is not FULL , calling push() add new data)
/// Start|-------------|
/// |-------------| ( Initial SOFI )
/// |-------------| ( Initial SpscSofi )
/// (push() Called two times)
///
/// |-------------|
Expand All @@ -105,7 +107,7 @@ class SoFi
/// @param[out] valueOut storage of the pop'ed value
/// @concurrent restricted thread safe: single pop, single push no
/// pop or popIf calls from multiple contexts
/// @return false if sofi is empty, otherwise true
/// @return false if SpscSofi is empty, otherwise true
bool pop(ValueType& valueOut) noexcept;

/// @brief conditional pop call to provide an alternative for a peek
Expand All @@ -125,35 +127,35 @@ class SoFi
/// @endcode
/// @concurrent restricted thread safe: single pop, single push no
/// pop or popIf calls from multiple contexts
/// @return false if sofi is empty or when verificator returns false, otherwise true
/// @return false if SpscSofi is empty or when verificator returns false, otherwise true
template <typename Verificator_T>
bool popIf(ValueType& valueOut, const Verificator_T& verificator) noexcept;

/// @brief returns true if sofi is empty, otherwise false
/// @brief returns true if SpscSofi is empty, otherwise false
/// @note the use of this function is limited in the concurrency case. if you
/// call this and in another thread pop is called the result can be out
/// of date as soon as you require it
/// @concurrent unrestricted thread safe
bool empty() const noexcept;

/// @brief resizes sofi
/// @brief resizes SpscSofi
/// @param[in] newSize valid values are 0 < newSize < CapacityValue
/// @pre it is important that no pop or push calls occur during
/// this call
/// @concurrent not thread safe
bool setCapacity(const uint64_t newSize) noexcept;

/// @brief returns the capacity of sofi
/// @brief returns the capacity of SpscSofi
/// @concurrent unrestricted thread safe
uint64_t capacity() const noexcept;

/// @brief returns the current size of sofi
/// @brief returns the current size of SpscSofi
/// @concurrent unrestricted thread safe
uint64_t size() const noexcept;

private:
UninitializedArray<ValueType, INTERNAL_SOFI_SIZE> m_data;
uint64_t m_size = INTERNAL_SOFI_SIZE;
UninitializedArray<ValueType, INTERNAL_SPSC_SOFI_SIZE> m_data;
uint64_t m_size = INTERNAL_SPSC_SOFI_SIZE;

/// @brief the write/read pointers are "atomic pointers" so that they are not
/// reordered (read or written too late)
Expand All @@ -164,6 +166,6 @@ class SoFi
} // namespace concurrent
} // namespace iox

#include "iceoryx_hoofs/internal/concurrent/sofi.inl"
#include "iox/detail/spsc_sofi.inl"

#endif // IOX_HOOFS_CONCURRENT_SOFI_HPP
#endif // IOX_HOOFS_CONCURRENT_BUFFER_SPSC_SOFI_HPP
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,24 @@
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
#ifndef IOX_HOOFS_CONCURRENT_SOFI_INL
#define IOX_HOOFS_CONCURRENT_SOFI_INL

#include "iceoryx_hoofs/internal/concurrent/sofi.hpp"
#ifndef IOX_HOOFS_CONCURRENT_BUFFER_SPSC_SOFI_INL
#define IOX_HOOFS_CONCURRENT_BUFFER_SPSC_SOFI_INL

#include "iox/detail/spsc_sofi.hpp"

namespace iox
{
namespace concurrent
{
template <class ValueType, uint64_t CapacityValue>
uint64_t SoFi<ValueType, CapacityValue>::capacity() const noexcept
uint64_t SpscSofi<ValueType, CapacityValue>::capacity() const noexcept
{
return m_size - INTERNAL_SIZE_ADD_ON;
}

template <class ValueType, uint64_t CapacityValue>
uint64_t SoFi<ValueType, CapacityValue>::size() const noexcept
uint64_t SpscSofi<ValueType, CapacityValue>::size() const noexcept
{
uint64_t readPosition{0};
uint64_t writePosition{0};
Expand All @@ -45,10 +46,10 @@ uint64_t SoFi<ValueType, CapacityValue>::size() const noexcept
}

template <class ValueType, uint64_t CapacityValue>
bool SoFi<ValueType, CapacityValue>::setCapacity(const uint64_t newSize) noexcept
bool SpscSofi<ValueType, CapacityValue>::setCapacity(const uint64_t newSize) noexcept
{
uint64_t newInternalSize = newSize + INTERNAL_SIZE_ADD_ON;
if (empty() && (newInternalSize <= INTERNAL_SOFI_SIZE))
if (empty() && (newInternalSize <= INTERNAL_SPSC_SOFI_SIZE))
{
m_size = newInternalSize;

Expand All @@ -62,7 +63,7 @@ bool SoFi<ValueType, CapacityValue>::setCapacity(const uint64_t newSize) noexcep
}

template <class ValueType, uint64_t CapacityValue>
bool SoFi<ValueType, CapacityValue>::empty() const noexcept
bool SpscSofi<ValueType, CapacityValue>::empty() const noexcept
{
uint64_t currentReadPosition{0};
bool isEmpty{false};
Expand All @@ -82,14 +83,14 @@ bool SoFi<ValueType, CapacityValue>::empty() const noexcept
}

template <class ValueType, uint64_t CapacityValue>
bool SoFi<ValueType, CapacityValue>::pop(ValueType& valueOut) noexcept
bool SpscSofi<ValueType, CapacityValue>::pop(ValueType& valueOut) noexcept
{
return popIf(valueOut, [](ValueType) { return true; });
}

template <class ValueType, uint64_t CapacityValue>
template <typename Verificator_T>
inline bool SoFi<ValueType, CapacityValue>::popIf(ValueType& valueOut, const Verificator_T& verificator) noexcept
inline bool SpscSofi<ValueType, CapacityValue>::popIf(ValueType& valueOut, const Verificator_T& verificator) noexcept
{
uint64_t currentReadPosition = m_readPosition.load(std::memory_order_acquire);
uint64_t nextReadPosition{0};
Expand Down Expand Up @@ -139,7 +140,7 @@ inline bool SoFi<ValueType, CapacityValue>::popIf(ValueType& valueOut, const Ver
}

template <class ValueType, uint64_t CapacityValue>
bool SoFi<ValueType, CapacityValue>::push(const ValueType& valueIn, ValueType& valueOut) noexcept
bool SpscSofi<ValueType, CapacityValue>::push(const ValueType& valueIn, ValueType& valueOut) noexcept
{
constexpr bool SOFI_OVERFLOW{false};

Expand Down Expand Up @@ -186,8 +187,7 @@ bool SoFi<ValueType, CapacityValue>::push(const ValueType& valueIn, ValueType& v
return !SOFI_OVERFLOW;
}


} // namespace concurrent
} // namespace iox

#endif // IOX_HOOFS_CONCURRENT_SOFI_INL
#endif // IOX_HOOFS_CONCURRENT_BUFFER_SPSC_SOFI_INL
4 changes: 2 additions & 2 deletions iceoryx_hoofs/include/iceoryx_hoofs/cxx/variant_queue.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
#define IOX_HOOFS_CXX_VARIANT_QUEUE_HPP

#include "iceoryx_hoofs/concurrent/resizeable_lockfree_queue.hpp"
#include "iceoryx_hoofs/internal/concurrent/sofi.hpp"
#include "iox/detail/spsc_fifo.hpp"
#include "iox/detail/spsc_sofi.hpp"
#include "iox/optional.hpp"
#include "iox/variant.hpp"

Expand Down Expand Up @@ -70,7 +70,7 @@ class VariantQueue
{
public:
using fifo_t = variant<concurrent::SpscFifo<ValueType, Capacity>,
concurrent::SoFi<ValueType, Capacity>,
concurrent::SpscSofi<ValueType, Capacity>,
concurrent::ResizeableLockFreeQueue<ValueType, Capacity>,
concurrent::ResizeableLockFreeQueue<ValueType, Capacity>>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ inline VariantQueue<ValueType, Capacity>::VariantQueue(const VariantQueueTypes t
}
case VariantQueueTypes::SoFi_SingleProducerSingleConsumer:
{
m_fifo.template emplace<concurrent::SoFi<ValueType, Capacity>>();
m_fifo.template emplace<concurrent::SpscSofi<ValueType, Capacity>>();
break;
}
case VariantQueueTypes::FiFo_MultiProducerSingleConsumer:
Expand Down
6 changes: 3 additions & 3 deletions iceoryx_hoofs/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,16 @@ iox_add_executable( TARGET ${PROJECT_PREFIX}_stresstests
FILES ${STRESSTESTS_SRC}
)

iox_add_executable( TARGET test_stress_sofi
iox_add_executable( TARGET test_stress_spsc_sofi
INCLUDE_DIRECTORIES .
LIBS ${TEST_LINK_LIBS}
LIBS_LINUX acl dl pthread rt
FILES stresstests/sofi/test_stress_sofi.cpp
FILES stresstests/sofi/test_stress_spsc_sofi.cpp
)

add_subdirectory(stresstests/benchmark_optional_and_expected)

target_compile_options(${PROJECT_PREFIX}_moduletests PRIVATE ${ICEORYX_TEST_CXX_FLAGS})
target_compile_options(${PROJECT_PREFIX}_mocktests PRIVATE ${ICEORYX_TEST_CXX_FLAGS})
target_compile_options(${PROJECT_PREFIX}_integrationtests PRIVATE ${ICEORYX_TEST_CXX_FLAGS})
target_compile_options(test_stress_sofi PRIVATE ${ICEORYX_TEST_CXX_FLAGS})
target_compile_options(test_stress_spsc_sofi PRIVATE ${ICEORYX_TEST_CXX_FLAGS})
Loading

0 comments on commit 514f0b2

Please sign in to comment.