iceoryx_hoofs  2.0.2
lockfree_queue.hpp
1 // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved.
2 // Copyright (c) 2020 - 2021 by Apex.AI Inc. All rights reserved.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 // SPDX-License-Identifier: Apache-2.0
17 
18 #ifndef IOX_HOOFS_CONCURRENT_LOCKFREE_QUEUE_HPP
19 #define IOX_HOOFS_CONCURRENT_LOCKFREE_QUEUE_HPP
20 
21 #include "iceoryx_hoofs/cxx/optional.hpp"
22 #include "iceoryx_hoofs/internal/concurrent/lockfree_queue/buffer.hpp"
23 #include "iceoryx_hoofs/internal/concurrent/lockfree_queue/index_queue.hpp"
24 
25 #include <atomic>
26 
27 
28 namespace iox
29 {
30 namespace concurrent
31 {
34 template <typename ElementType, uint64_t Capacity>
36 {
37  public:
38  using element_t = ElementType;
39 
41  LockFreeQueue() noexcept;
42 
43  ~LockFreeQueue() noexcept = default;
44 
45  // remark: a thread-safe and lockfree implementation of copy seems impossible
46  // but unsafe copying (i.e. where synchronization is up to the user) would be possible
47  // can be implemented when it is needed
48  LockFreeQueue(const LockFreeQueue&) = delete;
49  LockFreeQueue(LockFreeQueue&&) = delete;
50  LockFreeQueue& operator=(const LockFreeQueue&) = delete;
51  LockFreeQueue& operator=(LockFreeQueue&&) = delete;
52 
55  constexpr uint64_t capacity() const noexcept;
56 
61  bool tryPush(ElementType&& value) noexcept;
62 
67  bool tryPush(const ElementType& value) noexcept;
68 
74  iox::cxx::optional<ElementType> push(const ElementType& value) noexcept;
75 
81  iox::cxx::optional<ElementType> push(ElementType&& value) noexcept;
82 
86  iox::cxx::optional<ElementType> pop() noexcept;
87 
94  bool empty() const noexcept;
95 
101  uint64_t size() const noexcept;
102 
103  protected:
104  using Queue = IndexQueue<Capacity>;
105  using BufferIndex = typename Queue::value_t;
106 
107  // remark: actually m_freeIndices do not have to be in a queue, it could be another
108  // multi-push multi-pop capable lockfree container (e.g. a stack or a list)
109  Queue m_freeIndices;
110 
111  // required to be a queue for LockFreeQueue to exhibit FIFO behaviour
112  Queue m_usedIndices;
113 
114  Buffer<ElementType, Capacity, BufferIndex> m_buffer;
115 
116  std::atomic<uint64_t> m_size{0u};
117 
118  // template is needed to distinguish between lvalue and rvalue T references
119  // (universal reference type deduction)
120  template <typename T>
121  void writeBufferAt(const BufferIndex&, T&&) noexcept;
122 
123  // needed to avoid code duplication (via universal reference type deduction)
124  template <typename T>
125  iox::cxx::optional<ElementType> pushImpl(T&& value) noexcept;
126 
127  cxx::optional<ElementType> readBufferAt(const BufferIndex&) noexcept;
128 };
129 } // namespace concurrent
130 } // namespace iox
131 
132 #include "iceoryx_hoofs/internal/concurrent/lockfree_queue/lockfree_queue.inl"
133 
134 #endif // IOX_HOOFS_CONCURRENT_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
LockFreeQueue() noexcept
creates and initalizes an empty LockFreeQueue
constexpr uint64_t capacity() const noexcept
returns the capacity of the queue
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
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 ...
building block to easily create free function for logging in a library context
Definition: lockfree_queue.hpp:29