Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e7efb10
doc: misc: formatted_output: Add section for cbprintf packaging
nordic-krch Mar 29, 2021
36c1c12
lib: os: Add mpsc (multiple producer, single consumer) packet buffer
nordic-krch Jan 14, 2021
d163a83
lib: os: mpsc_pbuf: Add optional debug features
nordic-krch Mar 19, 2021
ad4fc07
tests: lib: Add test for mpsc_pbuf
nordic-krch Jan 14, 2021
9db6abb
doc: misc: Add documentation for MPSC Packet Buffer
nordic-krch Mar 31, 2021
f004fec
bluetooth: Add cast to forward declared struct
nordic-krch Mar 22, 2021
0d2135b
net: l2: bluetooth: Add cast to forward declared struct
nordic-krch Mar 23, 2021
1cfe6e9
logging: Refactor in preparation for logging v2
nordic-krch Jan 28, 2021
69663da
logging: Add logging v2 implementation for log_msg
nordic-krch Nov 19, 2020
07e0548
logging: log_output: Extend to support log_msg2 parsing
nordic-krch Dec 4, 2020
f381ca8
logging: Adapt logger to support both versions
nordic-krch Dec 22, 2020
65266bd
tests: logging: Add test for log_msg2
nordic-krch Dec 21, 2020
f394973
logging: Add LOG_PRINTK macro for printing via logging
nordic-krch Feb 4, 2021
1e495ef
tests: logging: Add benchmark test
nordic-krch Mar 29, 2021
faef903
doc: logging: Add documentation for logging v2
nordic-krch Apr 1, 2021
0a8b760
logging: backend_uart: Adapt to support v2 api
nordic-krch Dec 22, 2020
f660c72
logging: Add v2 support to native_posix backend
nordic-krch Jan 26, 2021
70ab8fe
logging: Add v2 support to RTT backend
nordic-krch Jan 27, 2021
3d00a13
logging: Adapt ADSP backend to v2
nordic-krch Jan 28, 2021
b3bcad5
shell: Add support for logging v2
nordic-krch Jan 29, 2021
c074e84
manifest: Temporary point to sof repo with MAX workaround
nordic-krch Mar 23, 2021
0206243
net: lib: openthread: logging: Refactor logging function
nordic-krch Apr 13, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/reference/data_structures/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ needed will be provided by the user.

slist.rst
dlist.rst
mpsc_pbuf.rst
rbtree.rst
ring_buffers.rst
147 changes: 147 additions & 0 deletions doc/reference/data_structures/mpsc_pbuf.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
.. _mpsc_pbuf:

Multi Producer Single Consumer Packet Buffer
============================================

A :dfn:`Multi Producer Single Consumer Packet Buffer (MPSC_PBUF)` is a circular
buffer, whose contents are stored in first-in-first-out order. Variable size
packets are stored in the buffer. Packet buffer works under assumption that there
is a single context that consumes the data. However, it is possible that another
context may interfere to flush the data and never come back (panic case).
Packet is produced in two steps: first requested amount of data is allocated,
producer fills the data and commits it. Consuming a packet is also performed in
two steps: consumer claims the packet, gets pointer to it and length and later
on packet is freed. This approach reduces memory copying.

A :dfn:`MPSC Packet Buffer` has the following key properties:

* Allocate, commit scheme used for packet producing.
* Claim, free scheme used for packet consuming.
* Allocator ensures that continue memory of requested length is allocated.
* Following policies can be applied when requested space cannot be allocated:

* **Overwrite** - oldest entries are dropped until requested amount of memory can
be allocated. For each dropped packet user callback is called.
* **No overwrite** - When requested amount of space cannot be allocated,
allocation fails.
* Dedicated, optimized API for storing short packets.
* Allocation with timeout.

Internals
---------

Each packet in the buffer contains ``MPSC_PBUF`` specific header which is used
for internal management. Header consists of 2 bit flags. In order to optimize
memory usage, header can be added on top of the user header using
:c:macro:`MPSC_PBUF_HDR` and remaining bits in the first word can be application
specific. Header consists of following flags:

* valid - bit set to one when packet contains valid user packet
* busy - bit set when packet is being consumed (claimed but not free)

Header state:

+-------+------+----------------------+
| valid | busy | description |
+-------+------+----------------------+
| 0 | 0 | space is free |
+-------+------+----------------------+
| 1 | 0 | valid packet |
+-------+------+----------------------+
| 1 | 1 | claimed valid packet |
+-------+------+----------------------+
| 0 | 1 | internal skip packet |
+-------+------+----------------------+

Packet buffer space contains free space, valid user packets and internal skip
packets. Internal skip packets indicates padding, e.g. at the of the buffer.

Allocation
^^^^^^^^^^

Using pairs for read and write indexes, available space is determined. If
space can be allocated, temporary write index is moved and pointer to a space
witing buffer is returned. Packet header is reset. If allocation required
wrapping of the write index, a skip packet is added to the end of buffer. If
space cannot be allocated and overwrite is disabled then ``NULL`` pointer is
returned or context blocks if allocation was with timeout.

Allocation with overwrite
^^^^^^^^^^^^^^^^^^^^^^^^^

If overwrite is enabled, oldest packets are dropped until requested amount of
space can be allocated. When packets are dropped ``busy`` flag is checked in the
header to ensure that currently consumed packet is not overwritten. In that case,
skip packet is added before busy packet and packets following the busy packet
are dropped. When busy packet is being freed, such situation is detected and
packet is converted to skip packet to avoid double processing.

Usage
-----

Packet header definition
^^^^^^^^^^^^^^^^^^^^^^^^

Packet header details can be found in :zephyr_file:`include/sys/mpsc_packet.h`.
API functions can be found in :zephyr_file:`include/sys/mpsc_pbuf.h`. Headers
are split to avoid include spam when declaring the packet.

User header structure must start with internal header:

.. code-block:: c

#include <sys/mpsc_packet.h>

struct foo_header {
MPSC_PBUF_HDR;
uint32_t length: 32 - MPSC_PBUF_HDR_BITS;
};

Packet buffer configuration
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Configuration structure contains buffer details, configuration flags and
callbacks. Following callbacks are used by the packet buffer:

* Drop notification - callback called whenever a packet is dropped due to
overwrite.
* Get packet length - callback to determine packet length

Packet producing
^^^^^^^^^^^^^^^^

Standard, two step method:

.. code-block:: c

foo_packet *packet = mpsc_pbuf_alloc(buffer, len, K_NO_WAIT);

fill_data(packet);

mpsc_pbuf_commit(buffer, packet);

Performance optimized storing of small packets:

* 32 bit word packet
* 32 bit word with pointer packet

Note that since packets are written by value, they should already contain
``valid`` bit set in the header.

.. code-block:: c

mpsc_pbuf_put_word(buffer, data);
mpsc_pbuf_put_word_ext(buffer, data, ptr);

Packet consuming
^^^^^^^^^^^^^^^^

Two step method:

.. code-block:: c

foo_packet *packet = mpsc_pbuf_claim(buffer);

process(packet);

mpsc_pbuf_free(buffer, packet);
Loading