iceoryx_hoofs 2.0.3
resizeable_lockfree_queue.hpp
1// Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15// SPDX-License-Identifier: Apache-2.0
16
17#ifndef IOX_HOOFS_CONCURRENT_RESIZEABLE_LOCKFREE_QUEUE_HPP
18#define IOX_HOOFS_CONCURRENT_RESIZEABLE_LOCKFREE_QUEUE_HPP
19
20#include "iceoryx_hoofs/concurrent/lockfree_queue.hpp"
21#include "iceoryx_hoofs/cxx/type_traits.hpp"
22#include "iceoryx_hoofs/cxx/vector.hpp"
23
24#include <atomic>
25
26namespace iox
27{
28namespace concurrent
29{
37
38// Remark: We use protected inheritance to make the base class methods inaccessible for the user.
39// We cannot use virtual functions since we need to use this class in shared memory.
40// Some of the methods need to be rewritten specifically for this class, others simply redirect
41// the call to the base class.
42//
43// Since supporting the resize (setCapacity) functionality has an impact on the runtime even
44// if the feature is not used, we provide a queue wihout resize functionality in an additional
45// base class that can be used separately.
46template <typename ElementType, uint64_t MaxCapacity>
47class ResizeableLockFreeQueue : protected LockFreeQueue<ElementType, MaxCapacity>
48{
49 private:
51
52 public:
53 using element_t = ElementType;
54 static constexpr uint64_t MAX_CAPACITY = MaxCapacity;
55
56 ResizeableLockFreeQueue() noexcept = default;
57 ~ResizeableLockFreeQueue() noexcept = default;
58
59 // deleted for now, can be implemented later if needed
60 // note: concurrent copying or moving in lockfree fashion is nontrivial
63 ResizeableLockFreeQueue& operator=(const ResizeableLockFreeQueue&) = delete;
65
66 ResizeableLockFreeQueue(const uint64_t initialCapacity) noexcept;
67
70 static constexpr uint64_t maxCapacity() noexcept;
71
72 using Base::empty;
73 using Base::pop;
74 using Base::size;
75 using Base::tryPush;
76
80 uint64_t capacity() const noexcept;
81
87 iox::cxx::optional<ElementType> push(const ElementType& value) noexcept;
88
94 iox::cxx::optional<ElementType> push(ElementType&& value) noexcept;
95
96 // overloads to set the capacity
97 // 1) The most general one allows providing a removeHandler to specify remove behavior.
98 // This could e.g. be to store them in a container.
99 // 2) The second overload discards removed elements.
100
108
114 template <typename Function,
115 typename = typename std::enable_if<cxx::is_invocable<Function, ElementType>::value>::type>
116 bool setCapacity(const uint64_t newCapacity, Function&& removeHandler) noexcept;
117
123 bool setCapacity(const uint64_t newCapacity) noexcept;
124
125 private:
126 using BufferIndex = typename Base::BufferIndex;
127 std::atomic<uint64_t> m_capacity{MaxCapacity};
128 // must be operator= otherwise it is undefined, see https://en.cppreference.com/w/cpp/atomic/ATOMIC_FLAG_INIT
129 std::atomic_flag m_resizeInProgress = ATOMIC_FLAG_INIT;
131
137 uint64_t increaseCapacity(const uint64_t toIncrease) noexcept;
138
146 template <typename Function>
147 uint64_t decreaseCapacity(const uint64_t toDecrease, Function&& removeHandler) noexcept;
148
152 bool tryGetUsedIndex(BufferIndex& index) noexcept;
153
154 template <typename T>
155 iox::cxx::optional<ElementType> pushImpl(T&& value) noexcept;
156};
157
158} // namespace concurrent
159} // namespace iox
160
161#include "iceoryx_hoofs/internal/concurrent/lockfree_queue/resizeable_lockfree_queue.inl"
162
163#endif // IOX_HOOFS_CONCURRENT_RESIZEABLE_LOCKFREE_QUEUE_HPP
implements a lock free queue (i.e. container with FIFO order) of elements of type T with a fixed Capa...
Definition: lockfree_queue.hpp:36
bool tryPush(ElementType &&value) noexcept
tries to insert value in FIFO order, moves the value internally
bool empty() const noexcept
check whether the queue is empty
uint64_t size() const noexcept
get the number of stored elements in the queue
iox::cxx::optional< ElementType > pop() noexcept
tries to remove value in FIFO order
implements a lock free queue (i.e. container with FIFO order) of elements of type T with a maximum ca...
Definition: resizeable_lockfree_queue.hpp:48
uint64_t capacity() const noexcept
returns the current capacity of the queue
static constexpr uint64_t maxCapacity() noexcept
returns the maximum capacity of the queue
iox::cxx::optional< ElementType > push(const ElementType &value) noexcept
inserts value in FIFO order, always succeeds by removing the oldest value when the queue is detected ...
bool setCapacity(const uint64_t newCapacity, Function &&removeHandler) noexcept
Set the capacity to some value.
Optional implementation from the C++17 standard with C++11. The interface is analog to the C++17 stan...
Definition: optional.hpp:69
building block to easily create free function for logging in a library context
Definition: lockfree_queue.hpp:29