iceoryx_hoofs 2.0.8
Loading...
Searching...
No Matches
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
61 ResizeableLockFreeQueue(const ResizeableLockFreeQueue&) = delete;
62 ResizeableLockFreeQueue(ResizeableLockFreeQueue&&) = delete;
63 ResizeableLockFreeQueue& operator=(const ResizeableLockFreeQueue&) = delete;
64 ResizeableLockFreeQueue& operator=(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
uint64_t capacity() const noexcept
returns the current capacity of the queue
bool tryPush(ElementType &&value) noexcept
tries to insert value in FIFO order, moves the value internally
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 empty() const noexcept
check whether the queue is empty
bool setCapacity(const uint64_t newCapacity, Function &&removeHandler) noexcept
Set the capacity to some value.
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
Optional implementation from the C++17 standard with C++11. The interface is analog to the C++17 stan...
Definition optional.hpp:69
C++11 compatible vector implementation. We needed to do some adjustments in the API since we do not u...
Definition vector.hpp:39
building block to easily create free function for logging in a library context
Definition lockfree_queue.hpp:29