- ================
- CIRCULAR BUFFERS
- ================
+================
+Circular Buffers
+================
-By: David Howells <dhowells@redhat.com>
- Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+:Author: David Howells <dhowells@redhat.com>
+:Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Linux provides a number of features that can be used to implement circular
serialising them, and to handle multiple consumers by serialising them.
-Contents:
+.. Contents:
(*) What is a circular buffer?
- 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
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.
-
-============================
-MEASURING POWER-OF-2 BUFFERS
+Measuring power-of-2 buffers
============================
Calculation of the occupancy or the remaining capacity of an arbitrarily sized
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
-can be made use of by:
+can be made use of by::
#include <linux/circ_buf.h>
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);
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);
beginning of the buffer.
- (*) Measure the occupancy of a buffer:
+ (#) Measure the occupancy of a buffer::
CIRC_CNT(head_index, tail_index, buffer_size);
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);
Each of these macros will nominally return a value between 0 and buffer_size-1,
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,
but the consumer may still be depleting the buffer on another CPU and
moving the tail index.
To the consumer it will show an upper bound as the producer may be busy
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
producer may still be filling the buffer on another CPU and moving the
head index.
To the producer it will show an upper bound as the consumer may be busy
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
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.
-
-===========================================
-USING MEMORY BARRIERS WITH CIRCULAR BUFFERS
+Using memory barriers with circular buffers
===========================================
By using memory barriers in conjunction with circular buffers, you can avoid
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);
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);
against previous accesses.
-===============
-FURTHER READING
+Further reading
===============
See also Documentation/memory-barriers.txt for a description of Linux's memory