Template Class TACO

Nested Relationships

Nested Types

Class Documentation

template<typename T, typename Context, uint32_t MaxNumberOfContext = 500>
class TACO

TACO is an acronym for Thread Aware exChange Ownership. Exchanging data between thread needs some synchonization mechanism. This can be done with a mutex or atomics. If the data structure is larger than 64 bit or if more than one value need to be accessed in a synchronized manner, a mutex would be the only option. The TACO is a wait-free alternative to the mutex. Data can be exchanged between threads. The TACO is like a SoFi with one element, but with the possibility to read/write from multiple threads.

#include "iceoryx_hoofs/internal/concurrent/taco.hpp"

#include <cstdint>
#include <iostream>
#include <thread>

constexpr std::uint64_t TotalCount{1000000};
struct SyncedData
{
    std::uint64_t decrementCounter{TotalCount};
    std::uint64_t incrementCounter{0};
};

enum class ThreadContext : uint32_t
{
    Hardy,
    Laurel,
    END_OF_LIST
};

int main()
{
    concurrent::TACO<SyncedData, ThreadContext> taco(concurrent::TACOMode::DenyDataFromSameContext);
    constexpr auto producerContext {ThreadContext::Hardy};
    constexpr auto consumerContext {ThreadContext::Laurel};

    auto producer = std::thread([&] {
        SyncedData data;
        while (data.decrementCounter != 0)
        {
            data.decrementCounter--;
            data.incrementCounter++;
            taco.store(data, producerContext);
        }
    });
    auto consumer = std::thread([&] {
        SyncedData data;
        do
        {
            auto retVal = taco.take(consumerContext);
            if (retVal.has_value())
            {
                data = *retVal;
                if(data.decrementCounter + data.incrementCounter != TotalCount)
                {
                    std::cout << "Error! Counter not synchronized!" << std::endl;
                }
            }

        } while (data.decrementCounter != 0);
    });

    producer.join();
    consumer.join();

    std::cout << "Finished!" << std::endl;

    return 0;
}

Param T:

DataType to be stored

Param Context:

Enum class with all the thread context that access the TACO. The enum must start with 0, must have ascending values and the last vaule must be called END_OF_LIST.

Public Functions

inline TACO(TACOMode mode)

Create a TACO instance with the specified mode

Parameters:

mode[in] the TACO operates

TACO(const TACO&) = delete
TACO(TACO&&) = delete
TACO &operator=(const TACO&) = delete
TACO &operator=(TACO&&) = delete
inline cxx::optional<T> exchange(const T &data, Context context)

Takes the data from the TACO and supplies new data

Parameters:
  • data[in] to supply for consumption, it’s copied into a local cache in the TACO

  • context[in] of the thread which performs the exchange

Returns:

the data a previous operation supplied for consumption or nullopt_t if there was either no data or the data was supplied from the same context and the mode disallows data from the same context

inline cxx::optional<T> take(const Context context)

Takes the data which is ready for consumption. The data isn’t available for other access anymore.

Parameters:

context[in] of the thread which takes the data

Returns:

the data a previous operation supplied for consumption or nullopt_t if there was either no data or the data was supplied from the same context and the mode disallows data from the same context

inline void store(const T &data, const Context context)

Supplies data for consumption

Parameters:
  • data[in] to supply for consumption, it’s copied into a local cache in the TACO

  • context[in] of the thread which performs the exchange