circular-buffers.txt: standardize document format
Each text file under Documentation follows a different format. Some doesn't even have titles! Change its representation to follow the adopted standard, using ReST markups for it to be parseable by Sphinx: - Mark titles with ReST notation; - comment the contents table; - Use :Author: tag for authorship; - mark literal blocks as such; - use valid numbered list markups; - Don't capitalize titles. Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> Signed-off-by: Jonathan Corbet <corbet@lwn.net>
This commit is contained in:
parent
fdefdbca7e
commit
f1d8b71c5f
|
@ -1,9 +1,9 @@
|
||||||
================
|
================
|
||||||
CIRCULAR BUFFERS
|
Circular Buffers
|
||||||
================
|
================
|
||||||
|
|
||||||
By: David Howells <dhowells@redhat.com>
|
:Author: David Howells <dhowells@redhat.com>
|
||||||
Paul E. McKenney <paulmck@linux.vnet.ibm.com>
|
:Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
|
||||||
|
|
||||||
|
|
||||||
Linux provides a number of features that can be used to implement circular
|
Linux provides a number of features that can be used to implement circular
|
||||||
|
@ -20,7 +20,7 @@ producer and just one consumer. It is possible to handle multiple producers by
|
||||||
serialising them, and to handle multiple consumers by serialising them.
|
serialising them, and to handle multiple consumers by serialising them.
|
||||||
|
|
||||||
|
|
||||||
Contents:
|
.. Contents:
|
||||||
|
|
||||||
(*) What is a circular buffer?
|
(*) What is a circular buffer?
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@ Contents:
|
||||||
- The consumer.
|
- The consumer.
|
||||||
|
|
||||||
|
|
||||||
==========================
|
|
||||||
WHAT IS A CIRCULAR BUFFER?
|
What is a circular buffer?
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
First of all, what is a circular buffer? A circular buffer is a buffer of
|
First of all, what is a circular buffer? A circular buffer is a buffer of
|
||||||
|
@ -60,9 +60,7 @@ buffer, provided that neither index overtakes the other. The implementer must
|
||||||
be careful, however, as a region more than one unit in size may wrap the end of
|
be careful, however, as a region more than one unit in size may wrap the end of
|
||||||
the buffer and be broken into two segments.
|
the buffer and be broken into two segments.
|
||||||
|
|
||||||
|
Measuring power-of-2 buffers
|
||||||
============================
|
|
||||||
MEASURING POWER-OF-2 BUFFERS
|
|
||||||
============================
|
============================
|
||||||
|
|
||||||
Calculation of the occupancy or the remaining capacity of an arbitrarily sized
|
Calculation of the occupancy or the remaining capacity of an arbitrarily sized
|
||||||
|
@ -71,13 +69,13 @@ modulus (divide) instruction. However, if the buffer is of a power-of-2 size,
|
||||||
then a much quicker bitwise-AND instruction can be used instead.
|
then a much quicker bitwise-AND instruction can be used instead.
|
||||||
|
|
||||||
Linux provides a set of macros for handling power-of-2 circular buffers. These
|
Linux provides a set of macros for handling power-of-2 circular buffers. These
|
||||||
can be made use of by:
|
can be made use of by::
|
||||||
|
|
||||||
#include <linux/circ_buf.h>
|
#include <linux/circ_buf.h>
|
||||||
|
|
||||||
The macros are:
|
The macros are:
|
||||||
|
|
||||||
(*) Measure the remaining capacity of a buffer:
|
(#) Measure the remaining capacity of a buffer::
|
||||||
|
|
||||||
CIRC_SPACE(head_index, tail_index, buffer_size);
|
CIRC_SPACE(head_index, tail_index, buffer_size);
|
||||||
|
|
||||||
|
@ -85,7 +83,7 @@ The macros are:
|
||||||
can be inserted.
|
can be inserted.
|
||||||
|
|
||||||
|
|
||||||
(*) Measure the maximum consecutive immediate space in a buffer:
|
(#) Measure the maximum consecutive immediate space in a buffer::
|
||||||
|
|
||||||
CIRC_SPACE_TO_END(head_index, tail_index, buffer_size);
|
CIRC_SPACE_TO_END(head_index, tail_index, buffer_size);
|
||||||
|
|
||||||
|
@ -94,14 +92,14 @@ The macros are:
|
||||||
beginning of the buffer.
|
beginning of the buffer.
|
||||||
|
|
||||||
|
|
||||||
(*) Measure the occupancy of a buffer:
|
(#) Measure the occupancy of a buffer::
|
||||||
|
|
||||||
CIRC_CNT(head_index, tail_index, buffer_size);
|
CIRC_CNT(head_index, tail_index, buffer_size);
|
||||||
|
|
||||||
This returns the number of items currently occupying a buffer[2].
|
This returns the number of items currently occupying a buffer[2].
|
||||||
|
|
||||||
|
|
||||||
(*) Measure the non-wrapping occupancy of a buffer:
|
(#) Measure the non-wrapping occupancy of a buffer::
|
||||||
|
|
||||||
CIRC_CNT_TO_END(head_index, tail_index, buffer_size);
|
CIRC_CNT_TO_END(head_index, tail_index, buffer_size);
|
||||||
|
|
||||||
|
@ -112,7 +110,7 @@ The macros are:
|
||||||
Each of these macros will nominally return a value between 0 and buffer_size-1,
|
Each of these macros will nominally return a value between 0 and buffer_size-1,
|
||||||
however:
|
however:
|
||||||
|
|
||||||
[1] CIRC_SPACE*() are intended to be used in the producer. To the producer
|
(1) CIRC_SPACE*() are intended to be used in the producer. To the producer
|
||||||
they will return a lower bound as the producer controls the head index,
|
they will return a lower bound as the producer controls the head index,
|
||||||
but the consumer may still be depleting the buffer on another CPU and
|
but the consumer may still be depleting the buffer on another CPU and
|
||||||
moving the tail index.
|
moving the tail index.
|
||||||
|
@ -120,7 +118,7 @@ however:
|
||||||
To the consumer it will show an upper bound as the producer may be busy
|
To the consumer it will show an upper bound as the producer may be busy
|
||||||
depleting the space.
|
depleting the space.
|
||||||
|
|
||||||
[2] CIRC_CNT*() are intended to be used in the consumer. To the consumer they
|
(2) CIRC_CNT*() are intended to be used in the consumer. To the consumer they
|
||||||
will return a lower bound as the consumer controls the tail index, but the
|
will return a lower bound as the consumer controls the tail index, but the
|
||||||
producer may still be filling the buffer on another CPU and moving the
|
producer may still be filling the buffer on another CPU and moving the
|
||||||
head index.
|
head index.
|
||||||
|
@ -128,14 +126,12 @@ however:
|
||||||
To the producer it will show an upper bound as the consumer may be busy
|
To the producer it will show an upper bound as the consumer may be busy
|
||||||
emptying the buffer.
|
emptying the buffer.
|
||||||
|
|
||||||
[3] To a third party, the order in which the writes to the indices by the
|
(3) To a third party, the order in which the writes to the indices by the
|
||||||
producer and consumer become visible cannot be guaranteed as they are
|
producer and consumer become visible cannot be guaranteed as they are
|
||||||
independent and may be made on different CPUs - so the result in such a
|
independent and may be made on different CPUs - so the result in such a
|
||||||
situation will merely be a guess, and may even be negative.
|
situation will merely be a guess, and may even be negative.
|
||||||
|
|
||||||
|
Using memory barriers with circular buffers
|
||||||
===========================================
|
|
||||||
USING MEMORY BARRIERS WITH CIRCULAR BUFFERS
|
|
||||||
===========================================
|
===========================================
|
||||||
|
|
||||||
By using memory barriers in conjunction with circular buffers, you can avoid
|
By using memory barriers in conjunction with circular buffers, you can avoid
|
||||||
|
@ -152,10 +148,10 @@ time, and only one thing should be emptying a buffer at any one time, but the
|
||||||
two sides can operate simultaneously.
|
two sides can operate simultaneously.
|
||||||
|
|
||||||
|
|
||||||
THE PRODUCER
|
The producer
|
||||||
------------
|
------------
|
||||||
|
|
||||||
The producer will look something like this:
|
The producer will look something like this::
|
||||||
|
|
||||||
spin_lock(&producer_lock);
|
spin_lock(&producer_lock);
|
||||||
|
|
||||||
|
@ -193,10 +189,10 @@ ordering between the read of the index indicating that the consumer has
|
||||||
vacated a given element and the write by the producer to that same element.
|
vacated a given element and the write by the producer to that same element.
|
||||||
|
|
||||||
|
|
||||||
THE CONSUMER
|
The Consumer
|
||||||
------------
|
------------
|
||||||
|
|
||||||
The consumer will look something like this:
|
The consumer will look something like this::
|
||||||
|
|
||||||
spin_lock(&consumer_lock);
|
spin_lock(&consumer_lock);
|
||||||
|
|
||||||
|
@ -235,8 +231,7 @@ prevents the compiler from tearing the store, and enforces ordering
|
||||||
against previous accesses.
|
against previous accesses.
|
||||||
|
|
||||||
|
|
||||||
===============
|
Further reading
|
||||||
FURTHER READING
|
|
||||||
===============
|
===============
|
||||||
|
|
||||||
See also Documentation/memory-barriers.txt for a description of Linux's memory
|
See also Documentation/memory-barriers.txt for a description of Linux's memory
|
||||||
|
|
Loading…
Reference in New Issue