xref: /dpdk/doc/guides/prog_guide/ring_lib.rst (revision 0058f08d272ca712a20ed39cf54615c6ab81d701)
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
75fc1f2750SBernard Iremonger.. _pg_figure_4:
76fc1f2750SBernard Iremonger
77fc1f2750SBernard Iremonger**Figure 4. Ring Structure**
78fc1f2750SBernard Iremonger
79fc1f2750SBernard Iremonger.. image5_png has been replaced
80fc1f2750SBernard Iremonger
81fc1f2750SBernard Iremonger|ring1|
82fc1f2750SBernard Iremonger
83fc1f2750SBernard IremongerReferences for Ring Implementation in FreeBSD*
84fc1f2750SBernard Iremonger----------------------------------------------
85fc1f2750SBernard Iremonger
86fc1f2750SBernard IremongerThe following code was added in FreeBSD 8.0, and is used in some network device drivers (at least in Intel drivers):
87fc1f2750SBernard Iremonger
88fc1f2750SBernard 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>`_
89fc1f2750SBernard Iremonger
90fc1f2750SBernard 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>`_
91fc1f2750SBernard Iremonger
92fc1f2750SBernard IremongerLockless Ring Buffer in Linux*
93fc1f2750SBernard Iremonger------------------------------
94fc1f2750SBernard Iremonger
95fc1f2750SBernard IremongerThe following is a link describing the `Linux Lockless Ring Buffer Design <http://lwn.net/Articles/340400/>`_.
96fc1f2750SBernard Iremonger
97fc1f2750SBernard IremongerAdditional Features
98fc1f2750SBernard Iremonger-------------------
99fc1f2750SBernard Iremonger
100fc1f2750SBernard IremongerName
101fc1f2750SBernard Iremonger~~~~
102fc1f2750SBernard Iremonger
103fc1f2750SBernard IremongerA ring is identified by a unique name.
104fc1f2750SBernard IremongerIt is not possible to create two rings with the same name (rte_ring_create() returns NULL if this is attempted).
105fc1f2750SBernard Iremonger
106fc1f2750SBernard IremongerWater Marking
107fc1f2750SBernard Iremonger~~~~~~~~~~~~~
108fc1f2750SBernard Iremonger
109fc1f2750SBernard IremongerThe ring can have a high water mark (threshold).
110fc1f2750SBernard IremongerOnce an enqueue operation reaches the high water mark, the producer is notified, if the water mark is configured.
111fc1f2750SBernard Iremonger
112fc1f2750SBernard IremongerThis mechanism can be used, for example, to exert a back pressure on I/O to inform the LAN to PAUSE.
113fc1f2750SBernard Iremonger
114fc1f2750SBernard IremongerDebug
115fc1f2750SBernard Iremonger~~~~~
116fc1f2750SBernard Iremonger
117fc1f2750SBernard IremongerWhen debug is enabled (CONFIG_RTE_LIBRTE_RING_DEBUG is set),
118fc1f2750SBernard Iremongerthe library stores some per-ring statistic counters about the number of enqueues/dequeues.
119fc1f2750SBernard IremongerThese statistics are per-core to avoid concurrent accesses or atomic operations.
120fc1f2750SBernard Iremonger
121fc1f2750SBernard IremongerUse Cases
122fc1f2750SBernard Iremonger---------
123fc1f2750SBernard Iremonger
124fc1f2750SBernard IremongerUse cases for the Ring library include:
125fc1f2750SBernard Iremonger
126fc1f2750SBernard Iremonger    *  Communication between applications in the Intel® DPDK
127fc1f2750SBernard Iremonger
128fc1f2750SBernard Iremonger    *  Used by memory pool allocator
129fc1f2750SBernard Iremonger
130fc1f2750SBernard IremongerAnatomy of a Ring Buffer
131fc1f2750SBernard Iremonger------------------------
132fc1f2750SBernard Iremonger
133fc1f2750SBernard IremongerThis section explains how a ring buffer operates.
134fc1f2750SBernard IremongerThe ring structure is composed of two head and tail couples; one is used by producers and one is used by the consumers.
135fc1f2750SBernard IremongerThe figures of the following sections refer to them as prod_head, prod_tail, cons_head and cons_tail.
136fc1f2750SBernard Iremonger
137fc1f2750SBernard IremongerEach figure represents a simplified state of the ring, which is a circular buffer.
138fc1f2750SBernard IremongerThe content of the function local variables is represented on the top of the figure,
139fc1f2750SBernard Iremongerand the content of ring structure is represented on the bottom of the figure.
140fc1f2750SBernard Iremonger
141fc1f2750SBernard IremongerSingle Producer Enqueue
142fc1f2750SBernard Iremonger~~~~~~~~~~~~~~~~~~~~~~~
143fc1f2750SBernard Iremonger
144fc1f2750SBernard IremongerThis section explains what occurs when a producer adds an object to the ring.
145fc1f2750SBernard IremongerIn this example, only the producer head and tail (prod_head and prod_tail) are modified,
146fc1f2750SBernard Iremongerand there is only one producer.
147fc1f2750SBernard Iremonger
148fc1f2750SBernard IremongerThe initial state is to have a prod_head and prod_tail pointing at the same location.
149fc1f2750SBernard Iremonger
150fc1f2750SBernard IremongerEnqueue First Step
151fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^^
152fc1f2750SBernard Iremonger
153fc1f2750SBernard IremongerFirst, *ring->prod_head* and ring->cons_tail are copied in local variables.
154fc1f2750SBernard IremongerThe prod_next local variable points to the next element of the table, or several elements after in case of bulk enqueue.
155fc1f2750SBernard Iremonger
156fc1f2750SBernard IremongerIf there is not enough room in the ring (this is detected by checking cons_tail), it returns an error.
157fc1f2750SBernard Iremonger
158fc1f2750SBernard Iremonger.. image6_png has been replaced
159fc1f2750SBernard Iremonger
160fc1f2750SBernard Iremonger|ring-enqueue1|
161fc1f2750SBernard Iremonger
162fc1f2750SBernard IremongerEnqueue Second Step
163fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^^^
164fc1f2750SBernard Iremonger
165fc1f2750SBernard IremongerThe second step is to modify *ring->prod_head* in ring structure to point to the same location as prod_next.
166fc1f2750SBernard Iremonger
167fc1f2750SBernard IremongerA pointer to the added object is copied in the ring (obj4).
168fc1f2750SBernard Iremonger
169fc1f2750SBernard Iremonger.. image7_png has been replaced
170fc1f2750SBernard Iremonger
171fc1f2750SBernard Iremonger|ring-enqueue2|
172fc1f2750SBernard Iremonger
173fc1f2750SBernard IremongerEnqueue Last Step
174fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^
175fc1f2750SBernard Iremonger
176fc1f2750SBernard 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*.
177fc1f2750SBernard IremongerThe enqueue operation is finished.
178fc1f2750SBernard Iremonger
179fc1f2750SBernard Iremonger.. image8_png has been replaced
180fc1f2750SBernard Iremonger
181fc1f2750SBernard Iremonger|ring-enqueue3|
182fc1f2750SBernard Iremonger
183fc1f2750SBernard IremongerSingle Consumer Dequeue
184fc1f2750SBernard Iremonger~~~~~~~~~~~~~~~~~~~~~~~
185fc1f2750SBernard Iremonger
186fc1f2750SBernard IremongerThis section explains what occurs when a consumer dequeues an object from the ring.
187fc1f2750SBernard IremongerIn this example, only the consumer head and tail (cons_head and cons_tail) are modified and there is only one consumer.
188fc1f2750SBernard Iremonger
189fc1f2750SBernard IremongerThe initial state is to have a cons_head and cons_tail pointing at the same location.
190fc1f2750SBernard Iremonger
191fc1f2750SBernard IremongerDequeue First Step
192fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^^
193fc1f2750SBernard Iremonger
194fc1f2750SBernard IremongerFirst, ring->cons_head and ring->prod_tail are copied in local variables.
195fc1f2750SBernard IremongerThe cons_next local variable points to the next element of the table, or several elements after in the case of bulk dequeue.
196fc1f2750SBernard Iremonger
197fc1f2750SBernard IremongerIf there are not enough objects in the ring (this is detected by checking prod_tail), it returns an error.
198fc1f2750SBernard Iremonger
199fc1f2750SBernard Iremonger.. image9_png has been replaced
200fc1f2750SBernard Iremonger
201fc1f2750SBernard Iremonger|ring-dequeue1|
202fc1f2750SBernard Iremonger
203fc1f2750SBernard IremongerDequeue Second Step
204fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^^^
205fc1f2750SBernard Iremonger
206fc1f2750SBernard IremongerThe second step is to modify ring->cons_head in the ring structure to point to the same location as cons_next.
207fc1f2750SBernard Iremonger
208fc1f2750SBernard IremongerThe pointer to the dequeued object (obj1) is copied in the pointer given by the user.
209fc1f2750SBernard Iremonger
210fc1f2750SBernard Iremonger.. image10_png has been replaced
211fc1f2750SBernard Iremonger
212fc1f2750SBernard Iremonger|ring-dequeue2|
213fc1f2750SBernard Iremonger
214fc1f2750SBernard IremongerDequeue Last Step
215fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^
216fc1f2750SBernard Iremonger
217fc1f2750SBernard IremongerFinally, ring->cons_tail in the ring structure is modified to point to the same location as ring->cons_head.
218fc1f2750SBernard IremongerThe dequeue operation is finished.
219fc1f2750SBernard Iremonger
220fc1f2750SBernard Iremonger.. image11_png has been replaced
221fc1f2750SBernard Iremonger
222fc1f2750SBernard Iremonger|ring-dequeue3|
223fc1f2750SBernard Iremonger
224fc1f2750SBernard IremongerMultiple Producers Enqueue
225fc1f2750SBernard Iremonger~~~~~~~~~~~~~~~~~~~~~~~~~~
226fc1f2750SBernard Iremonger
227fc1f2750SBernard IremongerThis section explains what occurs when two producers concurrently add an object to the ring.
228fc1f2750SBernard IremongerIn this example, only the producer head and tail (prod_head and prod_tail) are modified.
229fc1f2750SBernard Iremonger
230fc1f2750SBernard IremongerThe initial state is to have a prod_head and prod_tail pointing at the same location.
231fc1f2750SBernard Iremonger
232fc1f2750SBernard IremongerMC Enqueue First Step
233fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^^^^^
234fc1f2750SBernard Iremonger
235fc1f2750SBernard IremongerOn both cores, *ring->prod_head* and ring->cons_tail are copied in local variables.
236fc1f2750SBernard IremongerThe prod_next local variable points to the next element of the table,
237fc1f2750SBernard Iremongeror several elements after in the case of bulk enqueue.
238fc1f2750SBernard Iremonger
239*0058f08dSPablo de LaraIf there is not enough room in the ring (this is detected by checking cons_tail), it returns an error.
240fc1f2750SBernard Iremonger
241fc1f2750SBernard Iremonger.. image12_png has been replaced
242fc1f2750SBernard Iremonger
243fc1f2750SBernard Iremonger|ring-mp-enqueue1|
244fc1f2750SBernard Iremonger
245fc1f2750SBernard IremongerMC Enqueue Second Step
246fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^^^^^^
247fc1f2750SBernard Iremonger
248fc1f2750SBernard IremongerThe second step is to modify ring->prod_head in the ring structure to point to the same location as prod_next.
249fc1f2750SBernard IremongerThis operation is done using a Compare And Swap (CAS) instruction, which does the following operations atomically:
250fc1f2750SBernard Iremonger
251fc1f2750SBernard Iremonger*   If ring->prod_head is different to local variable prod_head,
252fc1f2750SBernard Iremonger    the CAS operation fails, and the code restarts at first step.
253fc1f2750SBernard Iremonger
254fc1f2750SBernard Iremonger*   Otherwise, ring->prod_head is set to local prod_next,
255fc1f2750SBernard Iremonger    the CAS operation is successful, and processing continues.
256fc1f2750SBernard Iremonger
257fc1f2750SBernard IremongerIn the figure, the operation succeeded on core 1, and step one restarted on core 2.
258fc1f2750SBernard Iremonger
259fc1f2750SBernard Iremonger.. image13_png has been replaced
260fc1f2750SBernard Iremonger
261fc1f2750SBernard Iremonger|ring-mp-enqueue2|
262fc1f2750SBernard Iremonger
263fc1f2750SBernard IremongerMC Enqueue Third Step
264fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^^^^^
265fc1f2750SBernard Iremonger
266fc1f2750SBernard IremongerThe CAS operation is retried on core 2 with success.
267fc1f2750SBernard Iremonger
268fc1f2750SBernard IremongerThe core 1 updates one element of the ring(obj4), and the core 2 updates another one (obj5).
269fc1f2750SBernard Iremonger
270fc1f2750SBernard Iremonger.. image14_png has been replaced
271fc1f2750SBernard Iremonger
272fc1f2750SBernard Iremonger|ring-mp-enqueue3|
273fc1f2750SBernard Iremonger
274fc1f2750SBernard IremongerMC Enqueue Fourth Step
275fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^^^^^^
276fc1f2750SBernard Iremonger
277fc1f2750SBernard IremongerEach core now wants to update ring->prod_tail.
278fc1f2750SBernard IremongerA core can only update it if ring->prod_tail is equal to the prod_head local variable.
279fc1f2750SBernard IremongerThis is only true on core 1. The operation is finished on core 1.
280fc1f2750SBernard Iremonger
281fc1f2750SBernard Iremonger.. image15_png has been replaced
282fc1f2750SBernard Iremonger
283fc1f2750SBernard Iremonger|ring-mp-enqueue4|
284fc1f2750SBernard Iremonger
285fc1f2750SBernard IremongerMC Enqueue Last Step
286fc1f2750SBernard Iremonger^^^^^^^^^^^^^^^^^^^^
287fc1f2750SBernard Iremonger
288fc1f2750SBernard IremongerOnce ring->prod_tail is updated by core 1, core 2 is allowed to update it too.
289fc1f2750SBernard IremongerThe operation is also finished on core 2.
290fc1f2750SBernard Iremonger
291fc1f2750SBernard Iremonger.. image16_png has been replaced
292fc1f2750SBernard Iremonger
293fc1f2750SBernard Iremonger|ring-mp-enqueue5|
294fc1f2750SBernard Iremonger
295fc1f2750SBernard IremongerModulo 32-bit Indexes
296fc1f2750SBernard Iremonger~~~~~~~~~~~~~~~~~~~~~
297fc1f2750SBernard Iremonger
298fc1f2750SBernard IremongerIn the preceding figures, the prod_head, prod_tail, cons_head and cons_tail indexes are represented by arrows.
299fc1f2750SBernard IremongerIn the actual implementation, these values are not between 0 and size(ring)-1 as would be assumed.
300fc1f2750SBernard IremongerThe indexes are between 0 and 2^32 -1, and we mask their value when we access the pointer table (the ring itself).
301fc1f2750SBernard Iremonger32-bit modulo also implies that operations on indexes (such as, add/subtract) will automatically do 2^32 modulo
302fc1f2750SBernard Iremongerif the result overflows the 32-bit number range.
303fc1f2750SBernard Iremonger
304fc1f2750SBernard IremongerThe following are two examples that help to explain how indexes are used in a ring.
305fc1f2750SBernard Iremonger
306fc1f2750SBernard Iremonger.. note::
307fc1f2750SBernard Iremonger
308fc1f2750SBernard Iremonger    To simplify the explanation, operations with modulo 16-bit are used instead of modulo 32-bit.
309fc1f2750SBernard Iremonger    In addition, the four indexes are defined as unsigned 16-bit integers,
310fc1f2750SBernard Iremonger    as opposed to unsigned 32-bit integers in the more realistic case.
311fc1f2750SBernard Iremonger
312fc1f2750SBernard Iremonger.. image17_png has been replaced
313fc1f2750SBernard Iremonger
314fc1f2750SBernard Iremonger|ring-modulo1|
315fc1f2750SBernard Iremonger
316fc1f2750SBernard IremongerThis ring contains 11000 entries.
317fc1f2750SBernard Iremonger
318fc1f2750SBernard Iremonger.. image18_png has been replaced
319fc1f2750SBernard Iremonger
320fc1f2750SBernard Iremonger|ring-modulo2|
321fc1f2750SBernard Iremonger
322fc1f2750SBernard IremongerThis ring contains 12536 entries.
323fc1f2750SBernard Iremonger
324fc1f2750SBernard Iremonger.. note::
325fc1f2750SBernard Iremonger
326fc1f2750SBernard Iremonger    For ease of understanding, we use modulo 65536 operations in the above examples.
327fc1f2750SBernard Iremonger    In real execution cases, this is redundant for low efficiency, but is done automatically when the result overflows.
328fc1f2750SBernard Iremonger
329fc1f2750SBernard IremongerThe code always maintains a distance between producer and consumer between 0 and size(ring)-1.
330fc1f2750SBernard IremongerThanks to this property, we can do subtractions between 2 index values in a modulo-32bit base:
331fc1f2750SBernard Iremongerthat's why the overflow of the indexes is not a problem.
332fc1f2750SBernard Iremonger
333fc1f2750SBernard IremongerAt any time, entries and free_entries are between 0 and size(ring)-1,
334fc1f2750SBernard Iremongereven if only the first term of subtraction has overflowed:
335fc1f2750SBernard Iremonger
336fc1f2750SBernard Iremonger.. code-block:: c
337fc1f2750SBernard Iremonger
338fc1f2750SBernard Iremonger    uint32_t entries = (prod_tail - cons_head);
339fc1f2750SBernard Iremonger    uint32_t free_entries = (mask + cons_tail -prod_head);
340fc1f2750SBernard Iremonger
341fc1f2750SBernard IremongerReferences
342fc1f2750SBernard Iremonger----------
343fc1f2750SBernard Iremonger
344fc1f2750SBernard 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)
345fc1f2750SBernard Iremonger
346fc1f2750SBernard 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)
347fc1f2750SBernard Iremonger
348fc1f2750SBernard Iremonger    *   `Linux Lockless Ring Buffer Design <http://lwn.net/Articles/340400/>`_
349fc1f2750SBernard Iremonger
350fc1f2750SBernard Iremonger.. |ring1| image:: img/ring1.svg
351fc1f2750SBernard Iremonger
352fc1f2750SBernard Iremonger.. |ring-enqueue1| image:: img/ring-enqueue1.svg
353fc1f2750SBernard Iremonger
354fc1f2750SBernard Iremonger.. |ring-enqueue2| image:: img/ring-enqueue2.svg
355fc1f2750SBernard Iremonger
356fc1f2750SBernard Iremonger.. |ring-enqueue3| image:: img/ring-enqueue3.svg
357fc1f2750SBernard Iremonger
358fc1f2750SBernard Iremonger.. |ring-dequeue1| image:: img/ring-dequeue1.svg
359fc1f2750SBernard Iremonger
360fc1f2750SBernard Iremonger.. |ring-dequeue2| image:: img/ring-dequeue2.svg
361fc1f2750SBernard Iremonger
362fc1f2750SBernard Iremonger.. |ring-dequeue3| image:: img/ring-dequeue3.svg
363fc1f2750SBernard Iremonger
364fc1f2750SBernard Iremonger.. |ring-mp-enqueue1| image:: img/ring-mp-enqueue1.svg
365fc1f2750SBernard Iremonger
366fc1f2750SBernard Iremonger.. |ring-mp-enqueue2| image:: img/ring-mp-enqueue2.svg
367fc1f2750SBernard Iremonger
368fc1f2750SBernard Iremonger.. |ring-mp-enqueue3| image:: img/ring-mp-enqueue3.svg
369fc1f2750SBernard Iremonger
370fc1f2750SBernard Iremonger.. |ring-mp-enqueue4| image:: img/ring-mp-enqueue4.svg
371fc1f2750SBernard Iremonger
372fc1f2750SBernard Iremonger.. |ring-mp-enqueue5| image:: img/ring-mp-enqueue5.svg
373fc1f2750SBernard Iremonger
374fc1f2750SBernard Iremonger.. |ring-modulo1| image:: img/ring-modulo1.svg
375fc1f2750SBernard Iremonger
376fc1f2750SBernard Iremonger.. |ring-modulo2| image:: img/ring-modulo2.svg
377