xref: /dpdk/doc/guides/prog_guide/ring_lib.rst (revision 4a22e6ee3d2f8be8afd5b374a8916e232ab7fe97)
1fc1f2750SBernard Iremonger..  BSD LICENSE
2fc1f2750SBernard Iremonger    Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
3fc1f2750SBernard Iremonger    All rights reserved.
4fc1f2750SBernard Iremonger
5fc1f2750SBernard Iremonger    Redistribution and use in source and binary forms, with or without
6fc1f2750SBernard Iremonger    modification, are permitted provided that the following conditions
7fc1f2750SBernard Iremonger    are met:
8fc1f2750SBernard Iremonger
9fc1f2750SBernard Iremonger    * Redistributions of source code must retain the above copyright
10fc1f2750SBernard Iremonger    notice, this list of conditions and the following disclaimer.
11fc1f2750SBernard Iremonger    * Redistributions in binary form must reproduce the above copyright
12fc1f2750SBernard Iremonger    notice, this list of conditions and the following disclaimer in
13fc1f2750SBernard Iremonger    the documentation and/or other materials provided with the
14fc1f2750SBernard Iremonger    distribution.
15fc1f2750SBernard Iremonger    * Neither the name of Intel Corporation nor the names of its
16fc1f2750SBernard Iremonger    contributors may be used to endorse or promote products derived
17fc1f2750SBernard Iremonger    from this software without specific prior written permission.
18fc1f2750SBernard Iremonger
19fc1f2750SBernard Iremonger    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20fc1f2750SBernard Iremonger    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21fc1f2750SBernard Iremonger    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22fc1f2750SBernard Iremonger    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23fc1f2750SBernard Iremonger    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24fc1f2750SBernard Iremonger    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25fc1f2750SBernard Iremonger    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26fc1f2750SBernard Iremonger    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27fc1f2750SBernard Iremonger    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28fc1f2750SBernard Iremonger    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29fc1f2750SBernard Iremonger    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30fc1f2750SBernard Iremonger
31fc1f2750SBernard Iremonger.. _Ring_Library:
32fc1f2750SBernard Iremonger
33fc1f2750SBernard IremongerRing Library
34fc1f2750SBernard Iremonger============
35fc1f2750SBernard Iremonger
36fc1f2750SBernard IremongerThe ring allows the management of queues.
37fc1f2750SBernard IremongerInstead of having a linked list of infinite size, the rte_ring has the following properties:
38fc1f2750SBernard Iremonger
39fc1f2750SBernard Iremonger*   FIFO
40fc1f2750SBernard Iremonger
41fc1f2750SBernard Iremonger*   Maximum size is fixed, the pointers are stored in a table
42fc1f2750SBernard Iremonger
43fc1f2750SBernard Iremonger*   Lockless implementation
44fc1f2750SBernard Iremonger
45fc1f2750SBernard Iremonger*   Multi-consumer or single-consumer dequeue
46fc1f2750SBernard Iremonger
47fc1f2750SBernard Iremonger*   Multi-producer or single-producer enqueue
48fc1f2750SBernard Iremonger
49fc1f2750SBernard Iremonger*   Bulk dequeue - Dequeues the specified count of objects if successful; otherwise fails
50fc1f2750SBernard Iremonger
51fc1f2750SBernard Iremonger*   Bulk enqueue - Enqueues the specified count of objects if successful; otherwise fails
52fc1f2750SBernard Iremonger
53fc1f2750SBernard Iremonger*   Burst dequeue - Dequeue the maximum available objects if the specified count cannot be fulfilled
54fc1f2750SBernard Iremonger
55fc1f2750SBernard Iremonger*   Burst enqueue - Enqueue the maximum available objects if the specified count cannot be fulfilled
56fc1f2750SBernard Iremonger
57fc1f2750SBernard IremongerThe advantages of this data structure over a linked list queue are as follows:
58fc1f2750SBernard Iremonger
59fc1f2750SBernard Iremonger*   Faster; only requires a single Compare-And-Swap instruction of sizeof(void \*) instead of several double-Compare-And-Swap instructions.
60fc1f2750SBernard Iremonger
61fc1f2750SBernard Iremonger*   Simpler than a full lockless queue.
62fc1f2750SBernard Iremonger
63fc1f2750SBernard Iremonger*   Adapted to bulk enqueue/dequeue operations.
64fc1f2750SBernard Iremonger    As pointers are stored in a table, a dequeue of several objects will not produce as many cache misses as in a linked queue.
65fc1f2750SBernard Iremonger    Also, a bulk dequeue of many objects does not cost more than a dequeue of a simple object.
66fc1f2750SBernard Iremonger
67fc1f2750SBernard IremongerThe disadvantages:
68fc1f2750SBernard Iremonger
69fc1f2750SBernard Iremonger*   Size is fixed
70fc1f2750SBernard Iremonger
71fc1f2750SBernard Iremonger*   Having many rings costs more in terms of memory than a linked list queue. An empty ring contains at least N pointers.
72fc1f2750SBernard Iremonger
73fc1f2750SBernard IremongerA simplified representation of a Ring is shown in with consumer and producer head and tail pointers to objects stored in the data structure.
74fc1f2750SBernard Iremonger
75*4a22e6eeSJohn McNamara.. _figure_ring1:
76fc1f2750SBernard Iremonger
77*4a22e6eeSJohn McNamara.. figure:: img/ring1.*
78fc1f2750SBernard Iremonger
79*4a22e6eeSJohn McNamara   Ring Structure
80fc1f2750SBernard Iremonger
81fc1f2750SBernard Iremonger
82fc1f2750SBernard IremongerReferences for Ring Implementation in FreeBSD*
83fc1f2750SBernard Iremonger----------------------------------------------
84fc1f2750SBernard Iremonger
85fc1f2750SBernard IremongerThe following code was added in FreeBSD 8.0, and is used in some network device drivers (at least in Intel drivers):
86fc1f2750SBernard Iremonger
87fc1f2750SBernard Iremonger    * `bufring.h in FreeBSD <http://svn.freebsd.org/viewvc/base/release/8.0.0/sys/sys/buf_ring.h?revision=199625&amp;view=markup>`_
88fc1f2750SBernard Iremonger
89fc1f2750SBernard Iremonger    * `bufring.c in FreeBSD <http://svn.freebsd.org/viewvc/base/release/8.0.0/sys/kern/subr_bufring.c?revision=199625&amp;view=markup>`_
90fc1f2750SBernard Iremonger
91fc1f2750SBernard IremongerLockless Ring Buffer in Linux*
92fc1f2750SBernard Iremonger------------------------------
93fc1f2750SBernard Iremonger
94fc1f2750SBernard IremongerThe following is a link describing the `Linux Lockless Ring Buffer Design <http://lwn.net/Articles/340400/>`_.
95fc1f2750SBernard Iremonger
96fc1f2750SBernard IremongerAdditional Features
97fc1f2750SBernard Iremonger-------------------
98fc1f2750SBernard Iremonger
99fc1f2750SBernard IremongerName
100fc1f2750SBernard Iremonger~~~~
101fc1f2750SBernard Iremonger
102fc1f2750SBernard IremongerA ring is identified by a unique name.
103fc1f2750SBernard IremongerIt is not possible to create two rings with the same name (rte_ring_create() returns NULL if this is attempted).
104fc1f2750SBernard Iremonger
105fc1f2750SBernard IremongerWater Marking
106fc1f2750SBernard Iremonger~~~~~~~~~~~~~
107fc1f2750SBernard Iremonger
108fc1f2750SBernard IremongerThe ring can have a high water mark (threshold).
109fc1f2750SBernard IremongerOnce an enqueue operation reaches the high water mark, the producer is notified, if the water mark is configured.
110fc1f2750SBernard Iremonger
111fc1f2750SBernard IremongerThis mechanism can be used, for example, to exert a back pressure on I/O to inform the LAN to PAUSE.
112fc1f2750SBernard Iremonger
113fc1f2750SBernard IremongerDebug
114fc1f2750SBernard Iremonger~~~~~
115fc1f2750SBernard Iremonger
116fc1f2750SBernard IremongerWhen debug is enabled (CONFIG_RTE_LIBRTE_RING_DEBUG is set),
117fc1f2750SBernard Iremongerthe library stores some per-ring statistic counters about the number of enqueues/dequeues.
118fc1f2750SBernard IremongerThese statistics are per-core to avoid concurrent accesses or atomic operations.
119fc1f2750SBernard Iremonger
120fc1f2750SBernard IremongerUse Cases
121fc1f2750SBernard Iremonger---------
122fc1f2750SBernard Iremonger
123fc1f2750SBernard IremongerUse cases for the Ring library include:
124fc1f2750SBernard Iremonger
12548624fd9SSiobhan Butler    *  Communication between applications in the DPDK
126fc1f2750SBernard Iremonger
127fc1f2750SBernard Iremonger    *  Used by memory pool allocator
128fc1f2750SBernard Iremonger
129fc1f2750SBernard IremongerAnatomy of a Ring Buffer
130fc1f2750SBernard Iremonger------------------------
131fc1f2750SBernard Iremonger
132fc1f2750SBernard IremongerThis section explains how a ring buffer operates.
133fc1f2750SBernard IremongerThe ring structure is composed of two head and tail couples; one is used by producers and one is used by the consumers.
134fc1f2750SBernard IremongerThe figures of the following sections refer to them as prod_head, prod_tail, cons_head and cons_tail.
135fc1f2750SBernard Iremonger
136fc1f2750SBernard IremongerEach figure represents a simplified state of the ring, which is a circular buffer.
137fc1f2750SBernard IremongerThe content of the function local variables is represented on the top of the figure,
138fc1f2750SBernard Iremongerand the content of ring structure is represented on the bottom of the figure.
139fc1f2750SBernard Iremonger
140fc1f2750SBernard IremongerSingle Producer Enqueue
141fc1f2750SBernard Iremonger~~~~~~~~~~~~~~~~~~~~~~~
142fc1f2750SBernard Iremonger
143fc1f2750SBernard IremongerThis section explains what occurs when a producer adds an object to the ring.
144fc1f2750SBernard IremongerIn this example, only the producer head and tail (prod_head and prod_tail) are modified,
145fc1f2750SBernard Iremongerand there is only one producer.
146fc1f2750SBernard Iremonger
147fc1f2750SBernard IremongerThe initial state is to have a prod_head and prod_tail pointing at the same location.
148fc1f2750SBernard Iremonger
149fc1f2750SBernard IremongerEnqueue First Step
150fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^^
151fc1f2750SBernard Iremonger
152fc1f2750SBernard IremongerFirst, *ring->prod_head* and ring->cons_tail are copied in local variables.
153fc1f2750SBernard IremongerThe prod_next local variable points to the next element of the table, or several elements after in case of bulk enqueue.
154fc1f2750SBernard Iremonger
155fc1f2750SBernard IremongerIf there is not enough room in the ring (this is detected by checking cons_tail), it returns an error.
156fc1f2750SBernard Iremonger
157fc1f2750SBernard Iremonger
158*4a22e6eeSJohn McNamara.. _figure_ring-enqueue1:
159*4a22e6eeSJohn McNamara
160*4a22e6eeSJohn McNamara.. figure:: img/ring-enqueue1.*
161*4a22e6eeSJohn McNamara
162*4a22e6eeSJohn McNamara   Enqueue first step
163*4a22e6eeSJohn McNamara
164fc1f2750SBernard Iremonger
165fc1f2750SBernard IremongerEnqueue Second Step
166fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^^^
167fc1f2750SBernard Iremonger
168fc1f2750SBernard IremongerThe second step is to modify *ring->prod_head* in ring structure to point to the same location as prod_next.
169fc1f2750SBernard Iremonger
170fc1f2750SBernard IremongerA pointer to the added object is copied in the ring (obj4).
171fc1f2750SBernard Iremonger
172fc1f2750SBernard Iremonger
173*4a22e6eeSJohn McNamara.. _figure_ring-enqueue2:
174*4a22e6eeSJohn McNamara
175*4a22e6eeSJohn McNamara.. figure:: img/ring-enqueue2.*
176*4a22e6eeSJohn McNamara
177*4a22e6eeSJohn McNamara   Enqueue second step
178*4a22e6eeSJohn McNamara
179fc1f2750SBernard Iremonger
180fc1f2750SBernard IremongerEnqueue Last Step
181fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^
182fc1f2750SBernard Iremonger
183fc1f2750SBernard 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*.
184fc1f2750SBernard IremongerThe enqueue operation is finished.
185fc1f2750SBernard Iremonger
186fc1f2750SBernard Iremonger
187*4a22e6eeSJohn McNamara.. _figure_ring-enqueue3:
188*4a22e6eeSJohn McNamara
189*4a22e6eeSJohn McNamara.. figure:: img/ring-enqueue3.*
190*4a22e6eeSJohn McNamara
191*4a22e6eeSJohn McNamara   Enqueue last step
192*4a22e6eeSJohn McNamara
193fc1f2750SBernard Iremonger
194fc1f2750SBernard IremongerSingle Consumer Dequeue
195fc1f2750SBernard Iremonger~~~~~~~~~~~~~~~~~~~~~~~
196fc1f2750SBernard Iremonger
197fc1f2750SBernard IremongerThis section explains what occurs when a consumer dequeues an object from the ring.
198fc1f2750SBernard IremongerIn this example, only the consumer head and tail (cons_head and cons_tail) are modified and there is only one consumer.
199fc1f2750SBernard Iremonger
200fc1f2750SBernard IremongerThe initial state is to have a cons_head and cons_tail pointing at the same location.
201fc1f2750SBernard Iremonger
202fc1f2750SBernard IremongerDequeue First Step
203fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^^
204fc1f2750SBernard Iremonger
205fc1f2750SBernard IremongerFirst, ring->cons_head and ring->prod_tail are copied in local variables.
206fc1f2750SBernard IremongerThe cons_next local variable points to the next element of the table, or several elements after in the case of bulk dequeue.
207fc1f2750SBernard Iremonger
208fc1f2750SBernard IremongerIf there are not enough objects in the ring (this is detected by checking prod_tail), it returns an error.
209fc1f2750SBernard Iremonger
210fc1f2750SBernard Iremonger
211*4a22e6eeSJohn McNamara.. _figure_ring-dequeue1:
212*4a22e6eeSJohn McNamara
213*4a22e6eeSJohn McNamara.. figure:: img/ring-dequeue1.*
214*4a22e6eeSJohn McNamara
215*4a22e6eeSJohn McNamara   Dequeue last step
216*4a22e6eeSJohn McNamara
217fc1f2750SBernard Iremonger
218fc1f2750SBernard IremongerDequeue Second Step
219fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^^^
220fc1f2750SBernard Iremonger
221fc1f2750SBernard IremongerThe second step is to modify ring->cons_head in the ring structure to point to the same location as cons_next.
222fc1f2750SBernard Iremonger
223fc1f2750SBernard IremongerThe pointer to the dequeued object (obj1) is copied in the pointer given by the user.
224fc1f2750SBernard Iremonger
225fc1f2750SBernard Iremonger
226*4a22e6eeSJohn McNamara.. _figure_ring-dequeue2:
227*4a22e6eeSJohn McNamara
228*4a22e6eeSJohn McNamara.. figure:: img/ring-dequeue2.*
229*4a22e6eeSJohn McNamara
230*4a22e6eeSJohn McNamara   Dequeue second step
231*4a22e6eeSJohn McNamara
232fc1f2750SBernard Iremonger
233fc1f2750SBernard IremongerDequeue Last Step
234fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^
235fc1f2750SBernard Iremonger
236fc1f2750SBernard IremongerFinally, ring->cons_tail in the ring structure is modified to point to the same location as ring->cons_head.
237fc1f2750SBernard IremongerThe dequeue operation is finished.
238fc1f2750SBernard Iremonger
239fc1f2750SBernard Iremonger
240*4a22e6eeSJohn McNamara.. _figure_ring-dequeue3:
241*4a22e6eeSJohn McNamara
242*4a22e6eeSJohn McNamara.. figure:: img/ring-dequeue3.*
243*4a22e6eeSJohn McNamara
244*4a22e6eeSJohn McNamara   Dequeue last step
245*4a22e6eeSJohn McNamara
246fc1f2750SBernard Iremonger
247fc1f2750SBernard IremongerMultiple Producers Enqueue
248fc1f2750SBernard Iremonger~~~~~~~~~~~~~~~~~~~~~~~~~~
249fc1f2750SBernard Iremonger
250fc1f2750SBernard IremongerThis section explains what occurs when two producers concurrently add an object to the ring.
251fc1f2750SBernard IremongerIn this example, only the producer head and tail (prod_head and prod_tail) are modified.
252fc1f2750SBernard Iremonger
253fc1f2750SBernard IremongerThe initial state is to have a prod_head and prod_tail pointing at the same location.
254fc1f2750SBernard Iremonger
255*4a22e6eeSJohn McNamaraMultiple Consumer Enqueue First Step
256*4a22e6eeSJohn McNamara^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
257fc1f2750SBernard Iremonger
258fc1f2750SBernard IremongerOn both cores, *ring->prod_head* and ring->cons_tail are copied in local variables.
259fc1f2750SBernard IremongerThe prod_next local variable points to the next element of the table,
260fc1f2750SBernard Iremongeror several elements after in the case of bulk enqueue.
261fc1f2750SBernard Iremonger
2620058f08dSPablo de LaraIf there is not enough room in the ring (this is detected by checking cons_tail), it returns an error.
263fc1f2750SBernard Iremonger
264fc1f2750SBernard Iremonger
265*4a22e6eeSJohn McNamara.. _figure_ring-mp-enqueue1:
266fc1f2750SBernard Iremonger
267*4a22e6eeSJohn McNamara.. figure:: img/ring-mp-enqueue1.*
268*4a22e6eeSJohn McNamara
269*4a22e6eeSJohn McNamara   Multiple consumer enqueue first step
270*4a22e6eeSJohn McNamara
271*4a22e6eeSJohn McNamara
272*4a22e6eeSJohn McNamaraMultiple Consumer Enqueue Second Step
273*4a22e6eeSJohn McNamara^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
274fc1f2750SBernard Iremonger
275fc1f2750SBernard IremongerThe second step is to modify ring->prod_head in the ring structure to point to the same location as prod_next.
276fc1f2750SBernard IremongerThis operation is done using a Compare And Swap (CAS) instruction, which does the following operations atomically:
277fc1f2750SBernard Iremonger
278fc1f2750SBernard Iremonger*   If ring->prod_head is different to local variable prod_head,
279fc1f2750SBernard Iremonger    the CAS operation fails, and the code restarts at first step.
280fc1f2750SBernard Iremonger
281fc1f2750SBernard Iremonger*   Otherwise, ring->prod_head is set to local prod_next,
282fc1f2750SBernard Iremonger    the CAS operation is successful, and processing continues.
283fc1f2750SBernard Iremonger
284fc1f2750SBernard IremongerIn the figure, the operation succeeded on core 1, and step one restarted on core 2.
285fc1f2750SBernard Iremonger
286fc1f2750SBernard Iremonger
287*4a22e6eeSJohn McNamara.. _figure_ring-mp-enqueue2:
288fc1f2750SBernard Iremonger
289*4a22e6eeSJohn McNamara.. figure:: img/ring-mp-enqueue2.*
290*4a22e6eeSJohn McNamara
291*4a22e6eeSJohn McNamara   Multiple consumer enqueue second step
292*4a22e6eeSJohn McNamara
293*4a22e6eeSJohn McNamara
294*4a22e6eeSJohn McNamaraMultiple Consumer Enqueue Third Step
295*4a22e6eeSJohn McNamara^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
296fc1f2750SBernard Iremonger
297fc1f2750SBernard IremongerThe CAS operation is retried on core 2 with success.
298fc1f2750SBernard Iremonger
299fc1f2750SBernard IremongerThe core 1 updates one element of the ring(obj4), and the core 2 updates another one (obj5).
300fc1f2750SBernard Iremonger
301fc1f2750SBernard Iremonger
302*4a22e6eeSJohn McNamara.. _figure_ring-mp-enqueue3:
303fc1f2750SBernard Iremonger
304*4a22e6eeSJohn McNamara.. figure:: img/ring-mp-enqueue3.*
305*4a22e6eeSJohn McNamara
306*4a22e6eeSJohn McNamara   Multiple consumer enqueue third step
307*4a22e6eeSJohn McNamara
308*4a22e6eeSJohn McNamara
309*4a22e6eeSJohn McNamaraMultiple Consumer Enqueue Fourth Step
310*4a22e6eeSJohn McNamara^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
311fc1f2750SBernard Iremonger
312fc1f2750SBernard IremongerEach core now wants to update ring->prod_tail.
313fc1f2750SBernard IremongerA core can only update it if ring->prod_tail is equal to the prod_head local variable.
314fc1f2750SBernard IremongerThis is only true on core 1. The operation is finished on core 1.
315fc1f2750SBernard Iremonger
316fc1f2750SBernard Iremonger
317*4a22e6eeSJohn McNamara.. _figure_ring-mp-enqueue4:
318fc1f2750SBernard Iremonger
319*4a22e6eeSJohn McNamara.. figure:: img/ring-mp-enqueue4.*
320*4a22e6eeSJohn McNamara
321*4a22e6eeSJohn McNamara   Multiple consumer enqueue fourth step
322*4a22e6eeSJohn McNamara
323*4a22e6eeSJohn McNamara
324*4a22e6eeSJohn McNamaraMultiple Consumer Enqueue Last Step
325*4a22e6eeSJohn McNamara^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
326fc1f2750SBernard Iremonger
327fc1f2750SBernard IremongerOnce ring->prod_tail is updated by core 1, core 2 is allowed to update it too.
328fc1f2750SBernard IremongerThe operation is also finished on core 2.
329fc1f2750SBernard Iremonger
330fc1f2750SBernard Iremonger
331*4a22e6eeSJohn McNamara.. _figure_ring-mp-enqueue5:
332*4a22e6eeSJohn McNamara
333*4a22e6eeSJohn McNamara.. figure:: img/ring-mp-enqueue5.*
334*4a22e6eeSJohn McNamara
335*4a22e6eeSJohn McNamara   Multiple consumer enqueue last step
336*4a22e6eeSJohn McNamara
337fc1f2750SBernard Iremonger
338fc1f2750SBernard IremongerModulo 32-bit Indexes
339fc1f2750SBernard Iremonger~~~~~~~~~~~~~~~~~~~~~
340fc1f2750SBernard Iremonger
341fc1f2750SBernard IremongerIn the preceding figures, the prod_head, prod_tail, cons_head and cons_tail indexes are represented by arrows.
342fc1f2750SBernard IremongerIn the actual implementation, these values are not between 0 and size(ring)-1 as would be assumed.
343fc1f2750SBernard IremongerThe indexes are between 0 and 2^32 -1, and we mask their value when we access the pointer table (the ring itself).
344fc1f2750SBernard Iremonger32-bit modulo also implies that operations on indexes (such as, add/subtract) will automatically do 2^32 modulo
345fc1f2750SBernard Iremongerif the result overflows the 32-bit number range.
346fc1f2750SBernard Iremonger
347fc1f2750SBernard IremongerThe following are two examples that help to explain how indexes are used in a ring.
348fc1f2750SBernard Iremonger
349fc1f2750SBernard Iremonger.. note::
350fc1f2750SBernard Iremonger
351fc1f2750SBernard Iremonger    To simplify the explanation, operations with modulo 16-bit are used instead of modulo 32-bit.
352fc1f2750SBernard Iremonger    In addition, the four indexes are defined as unsigned 16-bit integers,
353fc1f2750SBernard Iremonger    as opposed to unsigned 32-bit integers in the more realistic case.
354fc1f2750SBernard Iremonger
355fc1f2750SBernard Iremonger
356*4a22e6eeSJohn McNamara.. _figure_ring-modulo1:
357*4a22e6eeSJohn McNamara
358*4a22e6eeSJohn McNamara.. figure:: img/ring-modulo1.*
359*4a22e6eeSJohn McNamara
360*4a22e6eeSJohn McNamara   Modulo 32-bit indexes - Example 1
361*4a22e6eeSJohn McNamara
362fc1f2750SBernard Iremonger
363fc1f2750SBernard IremongerThis ring contains 11000 entries.
364fc1f2750SBernard Iremonger
365fc1f2750SBernard Iremonger
366*4a22e6eeSJohn McNamara.. _figure_ring-modulo2:
367*4a22e6eeSJohn McNamara
368*4a22e6eeSJohn McNamara.. figure:: img/ring-modulo2.*
369*4a22e6eeSJohn McNamara
370*4a22e6eeSJohn McNamara      Modulo 32-bit indexes - Example 2
371*4a22e6eeSJohn McNamara
372fc1f2750SBernard Iremonger
373fc1f2750SBernard IremongerThis ring contains 12536 entries.
374fc1f2750SBernard Iremonger
375fc1f2750SBernard Iremonger.. note::
376fc1f2750SBernard Iremonger
377fc1f2750SBernard Iremonger    For ease of understanding, we use modulo 65536 operations in the above examples.
378fc1f2750SBernard Iremonger    In real execution cases, this is redundant for low efficiency, but is done automatically when the result overflows.
379fc1f2750SBernard Iremonger
380fc1f2750SBernard IremongerThe code always maintains a distance between producer and consumer between 0 and size(ring)-1.
381fc1f2750SBernard IremongerThanks to this property, we can do subtractions between 2 index values in a modulo-32bit base:
382fc1f2750SBernard Iremongerthat's why the overflow of the indexes is not a problem.
383fc1f2750SBernard Iremonger
384fc1f2750SBernard IremongerAt any time, entries and free_entries are between 0 and size(ring)-1,
385fc1f2750SBernard Iremongereven if only the first term of subtraction has overflowed:
386fc1f2750SBernard Iremonger
387fc1f2750SBernard Iremonger.. code-block:: c
388fc1f2750SBernard Iremonger
389fc1f2750SBernard Iremonger    uint32_t entries = (prod_tail - cons_head);
390fc1f2750SBernard Iremonger    uint32_t free_entries = (mask + cons_tail -prod_head);
391fc1f2750SBernard Iremonger
392fc1f2750SBernard IremongerReferences
393fc1f2750SBernard Iremonger----------
394fc1f2750SBernard Iremonger
395fc1f2750SBernard Iremonger    *   `bufring.h in FreeBSD <http://svn.freebsd.org/viewvc/base/release/8.0.0/sys/sys/buf_ring.h?revision=199625&amp;view=markup>`_ (version 8)
396fc1f2750SBernard Iremonger
397fc1f2750SBernard Iremonger    *   `bufring.c in FreeBSD <http://svn.freebsd.org/viewvc/base/release/8.0.0/sys/kern/subr_bufring.c?revision=199625&amp;view=markup>`_ (version 8)
398fc1f2750SBernard Iremonger
399fc1f2750SBernard Iremonger    *   `Linux Lockless Ring Buffer Design <http://lwn.net/Articles/340400/>`_
400