16 #ifndef IOX_UTILS_CONCURRENT_TACO_HPP
17 #define IOX_UTILS_CONCURRENT_TACO_HPP
19 #include "iceoryx_utils/cxx/helplets.hpp"
20 #include "iceoryx_utils/cxx/optional.hpp"
33 AccecptDataFromSameContext,
35 DenyDataFromSameContext
114 template <
typename T,
typename Context, u
int32_t MaxNumberOfContext = 500>
120 Context context{Context::END_OF_LIST};
126 std::atomic<uint32_t> m_pendingTransaction;
128 static constexpr uint32_t NumberOfContext =
static_cast<uint32_t
>(Context::END_OF_LIST);
132 uint32_t m_indices[NumberOfContext];
135 Transaction m_transactions[NumberOfContext + 1];
142 , m_pendingTransaction(NumberOfContext)
144 static_assert(std::is_enum<Context>::value,
"TACO Context must be an enum class!");
145 static_assert(std::is_convertible<Context, uint32_t>::value ==
false,
146 "TACO Context must be an enum class, not just an enum!");
147 static_assert(std::is_same<uint32_t,
typename std::underlying_type<Context>::type>::value,
148 "TACO Context underlying type must be uint32_t!");
149 static_assert(
static_cast<uint32_t
>(Context::END_OF_LIST) < MaxNumberOfContext,
150 "TACO exceeded max number of contexts!");
154 for (
auto& index : m_indices)
163 TACO& operator=(
const TACO&) =
delete;
173 cxx::Expects(context < Context::END_OF_LIST);
174 m_transactions[m_indices[
static_cast<uint32_t
>(context)]].data.emplace(data);
184 cxx::Expects(context < Context::END_OF_LIST);
193 void store(
const T& data,
const Context context)
195 cxx::Expects(context < Context::END_OF_LIST);
202 auto contextIndex =
static_cast<uint32_t
>(context);
203 auto transactionIndexOld = m_indices[contextIndex];
204 m_transactions[transactionIndexOld].context = context;
206 m_indices[contextIndex] = m_pendingTransaction.exchange(transactionIndexOld, std::memory_order_acq_rel);
207 auto transactionIndexNew = m_indices[contextIndex];
209 if (m_mode == TACOMode::AccecptDataFromSameContext || m_transactions[transactionIndexNew].context != context)
211 return std::move(m_transactions[transactionIndexNew].data);
214 m_transactions[transactionIndexNew].data.reset();
TACO is an acronym for Thread Aware exChange Ownership. Exchanging data between thread needs some syn...
Definition: taco.hpp:116
cxx::optional< T > take(const Context context)
Definition: taco.hpp:182
void store(const T &data, const Context context)
Definition: taco.hpp:193
cxx::optional< T > exchange(const T &data, Context context)
Definition: taco.hpp:171
TACO(TACOMode mode)
Definition: taco.hpp:140
Optional implementation from the C++17 standard with C++11. The interface is analog to the C++17 stan...
Definition: optional.hpp:63
building block to easily create free function for logging in a library context
Definition: lockfree_queue.hpp:28
Helper struct which is used to signal an empty optional. It is equivalent to no value.
Definition: optional.hpp:34