15630257fSFerruh Yigit.. SPDX-License-Identifier: BSD-3-Clause 25630257fSFerruh Yigit Copyright(c) 2010-2014 Intel Corporation. 3fc1f2750SBernard Iremonger 4fc1f2750SBernard Iremonger.. _Ring_Library: 5fc1f2750SBernard Iremonger 6fc1f2750SBernard IremongerRing Library 7fc1f2750SBernard Iremonger============ 8fc1f2750SBernard Iremonger 9fc1f2750SBernard IremongerThe ring allows the management of queues. 10fc1f2750SBernard IremongerInstead of having a linked list of infinite size, the rte_ring has the following properties: 11fc1f2750SBernard Iremonger 12fc1f2750SBernard Iremonger* FIFO 13fc1f2750SBernard Iremonger 14e89680d0SHonnappa Nagarahalli* Maximum size is fixed, the objects are stored in a table 15e89680d0SHonnappa Nagarahalli 16e89680d0SHonnappa Nagarahalli* Objects can be pointers or elements of multiple of 4 byte size 17fc1f2750SBernard Iremonger 18fc1f2750SBernard Iremonger* Lockless implementation 19fc1f2750SBernard Iremonger 20fc1f2750SBernard Iremonger* Multi-consumer or single-consumer dequeue 21fc1f2750SBernard Iremonger 22fc1f2750SBernard Iremonger* Multi-producer or single-producer enqueue 23fc1f2750SBernard Iremonger 24fc1f2750SBernard Iremonger* Bulk dequeue - Dequeues the specified count of objects if successful; otherwise fails 25fc1f2750SBernard Iremonger 26fc1f2750SBernard Iremonger* Bulk enqueue - Enqueues the specified count of objects if successful; otherwise fails 27fc1f2750SBernard Iremonger 28fc1f2750SBernard Iremonger* Burst dequeue - Dequeue the maximum available objects if the specified count cannot be fulfilled 29fc1f2750SBernard Iremonger 30fc1f2750SBernard Iremonger* Burst enqueue - Enqueue the maximum available objects if the specified count cannot be fulfilled 31fc1f2750SBernard Iremonger 32fc1f2750SBernard IremongerThe advantages of this data structure over a linked list queue are as follows: 33fc1f2750SBernard Iremonger 34e89680d0SHonnappa Nagarahalli* Faster; only requires a single 32 bit Compare-And-Swap instruction instead of several pointer size Compare-And-Swap instructions. 35fc1f2750SBernard Iremonger 36fc1f2750SBernard Iremonger* Simpler than a full lockless queue. 37fc1f2750SBernard Iremonger 38fc1f2750SBernard Iremonger* Adapted to bulk enqueue/dequeue operations. 39e89680d0SHonnappa Nagarahalli As objects are stored in a table, a dequeue of several objects will not produce as many cache misses as in a linked queue. 40fc1f2750SBernard Iremonger Also, a bulk dequeue of many objects does not cost more than a dequeue of a simple object. 41fc1f2750SBernard Iremonger 42fc1f2750SBernard IremongerThe disadvantages: 43fc1f2750SBernard Iremonger 44fc1f2750SBernard Iremonger* Size is fixed 45fc1f2750SBernard Iremonger 46e89680d0SHonnappa Nagarahalli* Having many rings costs more in terms of memory than a linked list queue. An empty ring contains at least N objects. 47fc1f2750SBernard Iremonger 48fc1f2750SBernard IremongerA simplified representation of a Ring is shown in with consumer and producer head and tail pointers to objects stored in the data structure. 49fc1f2750SBernard Iremonger 504a22e6eeSJohn McNamara.. _figure_ring1: 51fc1f2750SBernard Iremonger 524a22e6eeSJohn McNamara.. figure:: img/ring1.* 53fc1f2750SBernard Iremonger 544a22e6eeSJohn McNamara Ring Structure 55fc1f2750SBernard Iremonger 56fc1f2750SBernard Iremonger 57fc1f2750SBernard IremongerReferences for Ring Implementation in FreeBSD* 58fc1f2750SBernard Iremonger---------------------------------------------- 59fc1f2750SBernard Iremonger 60fc1f2750SBernard IremongerThe following code was added in FreeBSD 8.0, and is used in some network device drivers (at least in Intel drivers): 61fc1f2750SBernard Iremonger 62fc1f2750SBernard Iremonger * `bufring.h in FreeBSD <http://svn.freebsd.org/viewvc/base/release/8.0.0/sys/sys/buf_ring.h?revision=199625&view=markup>`_ 63fc1f2750SBernard Iremonger 64fc1f2750SBernard Iremonger * `bufring.c in FreeBSD <http://svn.freebsd.org/viewvc/base/release/8.0.0/sys/kern/subr_bufring.c?revision=199625&view=markup>`_ 65fc1f2750SBernard Iremonger 66fc1f2750SBernard IremongerLockless Ring Buffer in Linux* 67fc1f2750SBernard Iremonger------------------------------ 68fc1f2750SBernard Iremonger 69fc1f2750SBernard IremongerThe following is a link describing the `Linux Lockless Ring Buffer Design <http://lwn.net/Articles/340400/>`_. 70fc1f2750SBernard Iremonger 71fc1f2750SBernard IremongerAdditional Features 72fc1f2750SBernard Iremonger------------------- 73fc1f2750SBernard Iremonger 74fc1f2750SBernard IremongerName 75fc1f2750SBernard Iremonger~~~~ 76fc1f2750SBernard Iremonger 77fc1f2750SBernard IremongerA ring is identified by a unique name. 78fc1f2750SBernard IremongerIt is not possible to create two rings with the same name (rte_ring_create() returns NULL if this is attempted). 79fc1f2750SBernard Iremonger 80fc1f2750SBernard IremongerUse Cases 81fc1f2750SBernard Iremonger--------- 82fc1f2750SBernard Iremonger 83fc1f2750SBernard IremongerUse cases for the Ring library include: 84fc1f2750SBernard Iremonger 8548624fd9SSiobhan Butler * Communication between applications in the DPDK 86fc1f2750SBernard Iremonger 87fc1f2750SBernard Iremonger * Used by memory pool allocator 88fc1f2750SBernard Iremonger 89fc1f2750SBernard IremongerAnatomy of a Ring Buffer 90fc1f2750SBernard Iremonger------------------------ 91fc1f2750SBernard Iremonger 92fc1f2750SBernard IremongerThis section explains how a ring buffer operates. 93fc1f2750SBernard IremongerThe ring structure is composed of two head and tail couples; one is used by producers and one is used by the consumers. 94fc1f2750SBernard IremongerThe figures of the following sections refer to them as prod_head, prod_tail, cons_head and cons_tail. 95fc1f2750SBernard Iremonger 96fc1f2750SBernard IremongerEach figure represents a simplified state of the ring, which is a circular buffer. 97fc1f2750SBernard IremongerThe content of the function local variables is represented on the top of the figure, 98fc1f2750SBernard Iremongerand the content of ring structure is represented on the bottom of the figure. 99fc1f2750SBernard Iremonger 100fc1f2750SBernard IremongerSingle Producer Enqueue 101fc1f2750SBernard Iremonger~~~~~~~~~~~~~~~~~~~~~~~ 102fc1f2750SBernard Iremonger 103fc1f2750SBernard IremongerThis section explains what occurs when a producer adds an object to the ring. 104fc1f2750SBernard IremongerIn this example, only the producer head and tail (prod_head and prod_tail) are modified, 105fc1f2750SBernard Iremongerand there is only one producer. 106fc1f2750SBernard Iremonger 107fc1f2750SBernard IremongerThe initial state is to have a prod_head and prod_tail pointing at the same location. 108fc1f2750SBernard Iremonger 109fc1f2750SBernard IremongerEnqueue First Step 110fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^^ 111fc1f2750SBernard Iremonger 112fc1f2750SBernard IremongerFirst, *ring->prod_head* and ring->cons_tail are copied in local variables. 113fc1f2750SBernard IremongerThe prod_next local variable points to the next element of the table, or several elements after in case of bulk enqueue. 114fc1f2750SBernard Iremonger 115fc1f2750SBernard IremongerIf there is not enough room in the ring (this is detected by checking cons_tail), it returns an error. 116fc1f2750SBernard Iremonger 117fc1f2750SBernard Iremonger 1184a22e6eeSJohn McNamara.. _figure_ring-enqueue1: 1194a22e6eeSJohn McNamara 1204a22e6eeSJohn McNamara.. figure:: img/ring-enqueue1.* 1214a22e6eeSJohn McNamara 1224a22e6eeSJohn McNamara Enqueue first step 1234a22e6eeSJohn McNamara 124fc1f2750SBernard Iremonger 125fc1f2750SBernard IremongerEnqueue Second Step 126fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^^^ 127fc1f2750SBernard Iremonger 128fc1f2750SBernard IremongerThe second step is to modify *ring->prod_head* in ring structure to point to the same location as prod_next. 129fc1f2750SBernard Iremonger 130e89680d0SHonnappa NagarahalliThe added object is copied in the ring (obj4). 131fc1f2750SBernard Iremonger 132fc1f2750SBernard Iremonger 1334a22e6eeSJohn McNamara.. _figure_ring-enqueue2: 1344a22e6eeSJohn McNamara 1354a22e6eeSJohn McNamara.. figure:: img/ring-enqueue2.* 1364a22e6eeSJohn McNamara 1374a22e6eeSJohn McNamara Enqueue second step 1384a22e6eeSJohn McNamara 139fc1f2750SBernard Iremonger 140fc1f2750SBernard IremongerEnqueue Last Step 141fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^ 142fc1f2750SBernard Iremonger 143fc1f2750SBernard IremongerOnce the object is added in the ring, ring->prod_tail in the ring structure is modified to point to the same location as *ring->prod_head*. 144fc1f2750SBernard IremongerThe enqueue operation is finished. 145fc1f2750SBernard Iremonger 146fc1f2750SBernard Iremonger 1474a22e6eeSJohn McNamara.. _figure_ring-enqueue3: 1484a22e6eeSJohn McNamara 1494a22e6eeSJohn McNamara.. figure:: img/ring-enqueue3.* 1504a22e6eeSJohn McNamara 1514a22e6eeSJohn McNamara Enqueue last step 1524a22e6eeSJohn McNamara 153fc1f2750SBernard Iremonger 154fc1f2750SBernard IremongerSingle Consumer Dequeue 155fc1f2750SBernard Iremonger~~~~~~~~~~~~~~~~~~~~~~~ 156fc1f2750SBernard Iremonger 157fc1f2750SBernard IremongerThis section explains what occurs when a consumer dequeues an object from the ring. 158fc1f2750SBernard IremongerIn this example, only the consumer head and tail (cons_head and cons_tail) are modified and there is only one consumer. 159fc1f2750SBernard Iremonger 160fc1f2750SBernard IremongerThe initial state is to have a cons_head and cons_tail pointing at the same location. 161fc1f2750SBernard Iremonger 162fc1f2750SBernard IremongerDequeue First Step 163fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^^ 164fc1f2750SBernard Iremonger 165fc1f2750SBernard IremongerFirst, ring->cons_head and ring->prod_tail are copied in local variables. 166fc1f2750SBernard IremongerThe cons_next local variable points to the next element of the table, or several elements after in the case of bulk dequeue. 167fc1f2750SBernard Iremonger 168fc1f2750SBernard IremongerIf there are not enough objects in the ring (this is detected by checking prod_tail), it returns an error. 169fc1f2750SBernard Iremonger 170fc1f2750SBernard Iremonger 1714a22e6eeSJohn McNamara.. _figure_ring-dequeue1: 1724a22e6eeSJohn McNamara 1734a22e6eeSJohn McNamara.. figure:: img/ring-dequeue1.* 1744a22e6eeSJohn McNamara 1754a22e6eeSJohn McNamara Dequeue last step 1764a22e6eeSJohn McNamara 177fc1f2750SBernard Iremonger 178fc1f2750SBernard IremongerDequeue Second Step 179fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^^^ 180fc1f2750SBernard Iremonger 181fc1f2750SBernard IremongerThe second step is to modify ring->cons_head in the ring structure to point to the same location as cons_next. 182fc1f2750SBernard Iremonger 183e89680d0SHonnappa NagarahalliThe dequeued object (obj1) is copied in the pointer given by the user. 184fc1f2750SBernard Iremonger 185fc1f2750SBernard Iremonger 1864a22e6eeSJohn McNamara.. _figure_ring-dequeue2: 1874a22e6eeSJohn McNamara 1884a22e6eeSJohn McNamara.. figure:: img/ring-dequeue2.* 1894a22e6eeSJohn McNamara 1904a22e6eeSJohn McNamara Dequeue second step 1914a22e6eeSJohn McNamara 192fc1f2750SBernard Iremonger 193fc1f2750SBernard IremongerDequeue Last Step 194fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^ 195fc1f2750SBernard Iremonger 196fc1f2750SBernard IremongerFinally, ring->cons_tail in the ring structure is modified to point to the same location as ring->cons_head. 197fc1f2750SBernard IremongerThe dequeue operation is finished. 198fc1f2750SBernard Iremonger 199fc1f2750SBernard Iremonger 2004a22e6eeSJohn McNamara.. _figure_ring-dequeue3: 2014a22e6eeSJohn McNamara 2024a22e6eeSJohn McNamara.. figure:: img/ring-dequeue3.* 2034a22e6eeSJohn McNamara 2044a22e6eeSJohn McNamara Dequeue last step 2054a22e6eeSJohn McNamara 206fc1f2750SBernard Iremonger 207fc1f2750SBernard IremongerMultiple Producers Enqueue 208fc1f2750SBernard Iremonger~~~~~~~~~~~~~~~~~~~~~~~~~~ 209fc1f2750SBernard Iremonger 210fc1f2750SBernard IremongerThis section explains what occurs when two producers concurrently add an object to the ring. 211fc1f2750SBernard IremongerIn this example, only the producer head and tail (prod_head and prod_tail) are modified. 212fc1f2750SBernard Iremonger 213fc1f2750SBernard IremongerThe initial state is to have a prod_head and prod_tail pointing at the same location. 214fc1f2750SBernard Iremonger 215cdf5a9f3SShreyansh JainMultiple Producers Enqueue First Step 216cdf5a9f3SShreyansh Jain^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 217fc1f2750SBernard Iremonger 218fc1f2750SBernard IremongerOn both cores, *ring->prod_head* and ring->cons_tail are copied in local variables. 219fc1f2750SBernard IremongerThe prod_next local variable points to the next element of the table, 220fc1f2750SBernard Iremongeror several elements after in the case of bulk enqueue. 221fc1f2750SBernard Iremonger 2220058f08dSPablo de LaraIf there is not enough room in the ring (this is detected by checking cons_tail), it returns an error. 223fc1f2750SBernard Iremonger 224fc1f2750SBernard Iremonger 2254a22e6eeSJohn McNamara.. _figure_ring-mp-enqueue1: 226fc1f2750SBernard Iremonger 2274a22e6eeSJohn McNamara.. figure:: img/ring-mp-enqueue1.* 2284a22e6eeSJohn McNamara 229cdf5a9f3SShreyansh Jain Multiple producer enqueue first step 2304a22e6eeSJohn McNamara 2314a22e6eeSJohn McNamara 232cdf5a9f3SShreyansh JainMultiple Producers Enqueue Second Step 233cdf5a9f3SShreyansh Jain^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 234fc1f2750SBernard Iremonger 235fc1f2750SBernard IremongerThe second step is to modify ring->prod_head in the ring structure to point to the same location as prod_next. 236fc1f2750SBernard IremongerThis operation is done using a Compare And Swap (CAS) instruction, which does the following operations atomically: 237fc1f2750SBernard Iremonger 238fc1f2750SBernard Iremonger* If ring->prod_head is different to local variable prod_head, 239fc1f2750SBernard Iremonger the CAS operation fails, and the code restarts at first step. 240fc1f2750SBernard Iremonger 241fc1f2750SBernard Iremonger* Otherwise, ring->prod_head is set to local prod_next, 242fc1f2750SBernard Iremonger the CAS operation is successful, and processing continues. 243fc1f2750SBernard Iremonger 244fc1f2750SBernard IremongerIn the figure, the operation succeeded on core 1, and step one restarted on core 2. 245fc1f2750SBernard Iremonger 246fc1f2750SBernard Iremonger 2474a22e6eeSJohn McNamara.. _figure_ring-mp-enqueue2: 248fc1f2750SBernard Iremonger 2494a22e6eeSJohn McNamara.. figure:: img/ring-mp-enqueue2.* 2504a22e6eeSJohn McNamara 251cdf5a9f3SShreyansh Jain Multiple producer enqueue second step 2524a22e6eeSJohn McNamara 2534a22e6eeSJohn McNamara 254cdf5a9f3SShreyansh JainMultiple Producers Enqueue Third Step 255cdf5a9f3SShreyansh Jain^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 256fc1f2750SBernard Iremonger 257fc1f2750SBernard IremongerThe CAS operation is retried on core 2 with success. 258fc1f2750SBernard Iremonger 259fc1f2750SBernard IremongerThe core 1 updates one element of the ring(obj4), and the core 2 updates another one (obj5). 260fc1f2750SBernard Iremonger 261fc1f2750SBernard Iremonger 2624a22e6eeSJohn McNamara.. _figure_ring-mp-enqueue3: 263fc1f2750SBernard Iremonger 2644a22e6eeSJohn McNamara.. figure:: img/ring-mp-enqueue3.* 2654a22e6eeSJohn McNamara 266cdf5a9f3SShreyansh Jain Multiple producer enqueue third step 2674a22e6eeSJohn McNamara 2684a22e6eeSJohn McNamara 269cdf5a9f3SShreyansh JainMultiple Producers Enqueue Fourth Step 270cdf5a9f3SShreyansh Jain^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 271fc1f2750SBernard Iremonger 272fc1f2750SBernard IremongerEach core now wants to update ring->prod_tail. 273fc1f2750SBernard IremongerA core can only update it if ring->prod_tail is equal to the prod_head local variable. 274fc1f2750SBernard IremongerThis is only true on core 1. The operation is finished on core 1. 275fc1f2750SBernard Iremonger 276fc1f2750SBernard Iremonger 2774a22e6eeSJohn McNamara.. _figure_ring-mp-enqueue4: 278fc1f2750SBernard Iremonger 2794a22e6eeSJohn McNamara.. figure:: img/ring-mp-enqueue4.* 2804a22e6eeSJohn McNamara 281cdf5a9f3SShreyansh Jain Multiple producer enqueue fourth step 2824a22e6eeSJohn McNamara 2834a22e6eeSJohn McNamara 284cdf5a9f3SShreyansh JainMultiple Producers Enqueue Last Step 285cdf5a9f3SShreyansh Jain^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 286fc1f2750SBernard Iremonger 287fc1f2750SBernard IremongerOnce ring->prod_tail is updated by core 1, core 2 is allowed to update it too. 288fc1f2750SBernard IremongerThe operation is also finished on core 2. 289fc1f2750SBernard Iremonger 290fc1f2750SBernard Iremonger 2914a22e6eeSJohn McNamara.. _figure_ring-mp-enqueue5: 2924a22e6eeSJohn McNamara 2934a22e6eeSJohn McNamara.. figure:: img/ring-mp-enqueue5.* 2944a22e6eeSJohn McNamara 295cdf5a9f3SShreyansh Jain Multiple producer enqueue last step 2964a22e6eeSJohn McNamara 297fc1f2750SBernard Iremonger 298fc1f2750SBernard IremongerModulo 32-bit Indexes 299fc1f2750SBernard Iremonger~~~~~~~~~~~~~~~~~~~~~ 300fc1f2750SBernard Iremonger 301fc1f2750SBernard IremongerIn the preceding figures, the prod_head, prod_tail, cons_head and cons_tail indexes are represented by arrows. 302fc1f2750SBernard IremongerIn the actual implementation, these values are not between 0 and size(ring)-1 as would be assumed. 303e89680d0SHonnappa NagarahalliThe indexes are between 0 and 2^32 -1, and we mask their value when we access the object table (the ring itself). 304fc1f2750SBernard Iremonger32-bit modulo also implies that operations on indexes (such as, add/subtract) will automatically do 2^32 modulo 305fc1f2750SBernard Iremongerif the result overflows the 32-bit number range. 306fc1f2750SBernard Iremonger 307fc1f2750SBernard IremongerThe following are two examples that help to explain how indexes are used in a ring. 308fc1f2750SBernard Iremonger 309fc1f2750SBernard Iremonger.. note:: 310fc1f2750SBernard Iremonger 311fc1f2750SBernard Iremonger To simplify the explanation, operations with modulo 16-bit are used instead of modulo 32-bit. 312fc1f2750SBernard Iremonger In addition, the four indexes are defined as unsigned 16-bit integers, 313fc1f2750SBernard Iremonger as opposed to unsigned 32-bit integers in the more realistic case. 314fc1f2750SBernard Iremonger 315fc1f2750SBernard Iremonger 3164a22e6eeSJohn McNamara.. _figure_ring-modulo1: 3174a22e6eeSJohn McNamara 3184a22e6eeSJohn McNamara.. figure:: img/ring-modulo1.* 3194a22e6eeSJohn McNamara 3204a22e6eeSJohn McNamara Modulo 32-bit indexes - Example 1 3214a22e6eeSJohn McNamara 322fc1f2750SBernard Iremonger 323fc1f2750SBernard IremongerThis ring contains 11000 entries. 324fc1f2750SBernard Iremonger 325fc1f2750SBernard Iremonger 3264a22e6eeSJohn McNamara.. _figure_ring-modulo2: 3274a22e6eeSJohn McNamara 3284a22e6eeSJohn McNamara.. figure:: img/ring-modulo2.* 3294a22e6eeSJohn McNamara 3304a22e6eeSJohn McNamara Modulo 32-bit indexes - Example 2 3314a22e6eeSJohn McNamara 332fc1f2750SBernard Iremonger 333fc1f2750SBernard IremongerThis ring contains 12536 entries. 334fc1f2750SBernard Iremonger 335fc1f2750SBernard Iremonger.. note:: 336fc1f2750SBernard Iremonger 337fc1f2750SBernard Iremonger For ease of understanding, we use modulo 65536 operations in the above examples. 338fc1f2750SBernard Iremonger In real execution cases, this is redundant for low efficiency, but is done automatically when the result overflows. 339fc1f2750SBernard Iremonger 340fc1f2750SBernard IremongerThe code always maintains a distance between producer and consumer between 0 and size(ring)-1. 341fc1f2750SBernard IremongerThanks to this property, we can do subtractions between 2 index values in a modulo-32bit base: 342fc1f2750SBernard Iremongerthat's why the overflow of the indexes is not a problem. 343fc1f2750SBernard Iremonger 344fc1f2750SBernard IremongerAt any time, entries and free_entries are between 0 and size(ring)-1, 345fc1f2750SBernard Iremongereven if only the first term of subtraction has overflowed: 346fc1f2750SBernard Iremonger 347fc1f2750SBernard Iremonger.. code-block:: c 348fc1f2750SBernard Iremonger 349fc1f2750SBernard Iremonger uint32_t entries = (prod_tail - cons_head); 350fc1f2750SBernard Iremonger uint32_t free_entries = (mask + cons_tail -prod_head); 351fc1f2750SBernard Iremonger 352ebff988dSKonstantin AnanyevProducer/consumer synchronization modes 353ebff988dSKonstantin Ananyev--------------------------------------- 354ebff988dSKonstantin Ananyev 355ebff988dSKonstantin Ananyevrte_ring supports different synchronization modes for producers and consumers. 356ebff988dSKonstantin AnanyevThese modes can be specified at ring creation/init time via ``flags`` 357ebff988dSKonstantin Ananyevparameter. 358ebff988dSKonstantin AnanyevThat should help users to configure ring in the most suitable way for his 359ebff988dSKonstantin Ananyevspecific usage scenarios. 360ebff988dSKonstantin AnanyevCurrently supported modes: 361ebff988dSKonstantin Ananyev 362ebff988dSKonstantin AnanyevMP/MC (default one) 363ebff988dSKonstantin Ananyev~~~~~~~~~~~~~~~~~~~ 364ebff988dSKonstantin Ananyev 365ebff988dSKonstantin AnanyevMulti-producer (/multi-consumer) mode. This is a default enqueue (/dequeue) 366ebff988dSKonstantin Ananyevmode for the ring. In this mode multiple threads can enqueue (/dequeue) 367ebff988dSKonstantin Ananyevobjects to (/from) the ring. For 'classic' DPDK deployments (with one thread 368ebff988dSKonstantin Ananyevper core) this is usually the most suitable and fastest synchronization mode. 369ebff988dSKonstantin AnanyevAs a well known limitation - it can perform quite pure on some overcommitted 370ebff988dSKonstantin Ananyevscenarios. 371ebff988dSKonstantin Ananyev 372ebff988dSKonstantin AnanyevSP/SC 373ebff988dSKonstantin Ananyev~~~~~ 374ebff988dSKonstantin AnanyevSingle-producer (/single-consumer) mode. In this mode only one thread at a time 375ebff988dSKonstantin Ananyevis allowed to enqueue (/dequeue) objects to (/from) the ring. 376ebff988dSKonstantin Ananyev 377e6ba4731SKonstantin AnanyevMP_RTS/MC_RTS 378e6ba4731SKonstantin Ananyev~~~~~~~~~~~~~ 379e6ba4731SKonstantin Ananyev 380e6ba4731SKonstantin AnanyevMulti-producer (/multi-consumer) with Relaxed Tail Sync (RTS) mode. 381e6ba4731SKonstantin AnanyevThe main difference from the original MP/MC algorithm is that 382e6ba4731SKonstantin Ananyevtail value is increased not by every thread that finished enqueue/dequeue, 383e6ba4731SKonstantin Ananyevbut only by the last one. 384e6ba4731SKonstantin AnanyevThat allows threads to avoid spinning on ring tail value, 385e6ba4731SKonstantin Ananyevleaving actual tail value change to the last thread at a given instance. 386e6ba4731SKonstantin AnanyevThat technique helps to avoid the Lock-Waiter-Preemption (LWP) problem on tail 387e6ba4731SKonstantin Ananyevupdate and improves average enqueue/dequeue times on overcommitted systems. 388e6ba4731SKonstantin AnanyevTo achieve that RTS requires 2 64-bit CAS for each enqueue(/dequeue) operation: 389e6ba4731SKonstantin Ananyevone for head update, second for tail update. 390e6ba4731SKonstantin AnanyevIn comparison the original MP/MC algorithm requires one 32-bit CAS 391e6ba4731SKonstantin Ananyevfor head update and waiting/spinning on tail value. 392e6ba4731SKonstantin Ananyev 393*1cc363b8SKonstantin AnanyevMP_HTS/MC_HTS 394*1cc363b8SKonstantin Ananyev~~~~~~~~~~~~~ 395*1cc363b8SKonstantin Ananyev 396*1cc363b8SKonstantin AnanyevMulti-producer (/multi-consumer) with Head/Tail Sync (HTS) mode. 397*1cc363b8SKonstantin AnanyevIn that mode enqueue/dequeue operation is fully serialized: 398*1cc363b8SKonstantin Ananyevat any given moment only one enqueue/dequeue operation can proceed. 399*1cc363b8SKonstantin AnanyevThis is achieved by allowing a thread to proceed with changing ``head.value`` 400*1cc363b8SKonstantin Ananyevonly when ``head.value == tail.value``. 401*1cc363b8SKonstantin AnanyevBoth head and tail values are updated atomically (as one 64-bit value). 402*1cc363b8SKonstantin AnanyevTo achieve that 64-bit CAS is used by head update routine. 403*1cc363b8SKonstantin AnanyevThat technique also avoids the Lock-Waiter-Preemption (LWP) problem on tail 404*1cc363b8SKonstantin Ananyevupdate and helps to improve ring enqueue/dequeue behavior in overcommitted 405*1cc363b8SKonstantin Ananyevscenarios. Another advantage of fully serialized producer/consumer - 406*1cc363b8SKonstantin Ananyevit provides the ability to implement MT safe peek API for rte_ring. 407*1cc363b8SKonstantin Ananyev 408fc1f2750SBernard IremongerReferences 409fc1f2750SBernard Iremonger---------- 410fc1f2750SBernard Iremonger 411fc1f2750SBernard Iremonger * `bufring.h in FreeBSD <http://svn.freebsd.org/viewvc/base/release/8.0.0/sys/sys/buf_ring.h?revision=199625&view=markup>`_ (version 8) 412fc1f2750SBernard Iremonger 413fc1f2750SBernard Iremonger * `bufring.c in FreeBSD <http://svn.freebsd.org/viewvc/base/release/8.0.0/sys/kern/subr_bufring.c?revision=199625&view=markup>`_ (version 8) 414fc1f2750SBernard Iremonger 415fc1f2750SBernard Iremonger * `Linux Lockless Ring Buffer Design <http://lwn.net/Articles/340400/>`_ 416