Skip to content

iceoryx_utils/internal/concurrent/sofi.hpp🔗

Namespaces🔗

Name
iox
building block to easily create free function for logging in a library context
iox::concurrent

Classes🔗

Name
class iox::concurrent::SoFi
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 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 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 created , capacity can be is adjusted explicitly.

Source code🔗

// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
#ifndef IOX_UTILS_CONCURRENT_SOFI_HPP
#define IOX_UTILS_CONCURRENT_SOFI_HPP

#include "iceoryx_utils/platform/platform_correction.hpp"

#include <atomic>
#include <cstdint>
#include <cstring>
#include <functional>

namespace iox
{
namespace concurrent
{
template <class ValueType, uint64_t CapacityValue>
class SoFi
{
    static_assert(std::is_trivially_copyable<ValueType>::value, "SoFi can handle only trivially copyable data types");
    static_assert(2 <= ATOMIC_INT_LOCK_FREE, "SoFi is not able to run lock free on this data type");

    static constexpr uint32_t INTERNAL_SIZE_ADD_ON = 1;

    static constexpr uint32_t INTERNAL_SOFI_SIZE = CapacityValue + INTERNAL_SIZE_ADD_ON;

  public:
    SoFi() noexcept;

    bool push(const ValueType& valueOut, ValueType& f_paramOut_r) noexcept;

    bool pop(ValueType& valueOut) noexcept;

    template <typename Verificator_T>
    bool popIf(ValueType& valueOut, const Verificator_T& verificator) noexcept;

    bool empty() const noexcept;

    bool setCapacity(const uint64_t newSize) noexcept;

    uint64_t capacity() const noexcept;

    uint64_t size() const noexcept;

  private:
    ValueType m_data[INTERNAL_SOFI_SIZE];
    uint64_t m_size = INTERNAL_SOFI_SIZE;

    std::atomic<uint64_t> m_readPosition{0u};
    std::atomic<uint64_t> m_writePosition{0u};
};

} // namespace concurrent
} // namespace iox

#include "iceoryx_utils/internal/concurrent/sofi.inl"

#endif // IOX_UTILS_CONCURRENT_SOFI_HPP

Updated on 17 June 2021 at 11:15:26 CEST