.. _channel:

tmc::channel
-----------------------------------------------------------------------------------
:literal:`tmc::channel` is a high-performance async MPMC queue. It is unbounded and linearizable / FIFO.

Producers may enqueue items using :cpp:func:`push()<tmc::chan_tok::push>` or :cpp:func:`post()<tmc::chan_tok::post>`. Consumers may dequeue items using :cpp:func:`pull()<tmc::chan_tok::pull>`.
If the queue is empty, the consumer will suspend until an item is enqueued.

It's recommended to :cpp:func:`close()<tmc::chan_tok::close>` and :cpp:func:`drain()<tmc::chan_tok::drain>` the channel before destruction.
However, this is not required; if the channel is destroyed while elements remain inside, they will also be destroyed.

The channel can be configured by setting the Config template parameter which provides
:cpp:member:`BlockSize<tmc::chan_default_config::BlockSize>`,
:cpp:member:`PackingLevel<tmc::chan_default_config::PackingLevel>`,
and :cpp:member:`EmbedFirstBlock<tmc::chan_default_config::EmbedFirstBlock>`,
or at runtime by calling :cpp:func:`set_reuse_blocks()<tmc::chan_tok::set_reuse_blocks>`,
:cpp:func:`set_consumer_spins()<tmc::chan_tok::set_consumer_spins>`,
and :cpp:func:`set_heavy_load_threshold()<tmc::chan_tok::set_heavy_load_threshold>`.

Usage Example
-----------------------------------------------------------------------------------

.. code-block:: cpp

  #include "tmc/task.hpp"
  #include "tmc/spawn_tuple.hpp"
  #include "tmc/channel.hpp"

  tmc::task<void> producer(tmc::chan_tok<int> chan) {
    for (int i = 0; i < 100; ++i) {
      co_await chan.push(1);
    }
    co_await chan.drain();
  }

  tmc::task<void> consumer(tmc::chan_tok<int> chan) {
    while (auto data = co_await chan.pull()) {
      int& i = data.value();
      // do something with i
    }
  }

  tmc::task<void> chan_quickstart() {
    tmc::chan_tok<int> chan = tmc::make_channel<int>();
    co_await tmc::spawn_tuple(producer(chan), consumer(chan));
  }

API Reference
-----------------------------------------------------------------------------------
.. doxygenfunction:: tmc::make_channel()

.. doxygenclass:: tmc::chan_tok
  :members:

.. doxygenstruct:: tmc::chan_default_config
  :members:
