Documentation: update ring-buffer-design.txt

Fix typos, grammos, spellos, hyphenation.

Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Cc: Mel Gorman <mel@csn.ul.ie>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Randy Dunlap 2010-01-08 14:43:07 -08:00 committed by Linus Torvalds
parent 74dbdd239b
commit 006b4298f2

View File

@ -33,9 +33,9 @@ head_page - a pointer to the page that the reader will use next
tail_page - a pointer to the page that will be written to next
commit_page - a pointer to the page with the last finished non nested write.
commit_page - a pointer to the page with the last finished non-nested write.
cmpxchg - hardware assisted atomic transaction that performs the following:
cmpxchg - hardware-assisted atomic transaction that performs the following:
A = B iff previous A == C
@ -52,15 +52,15 @@ The Generic Ring Buffer
The ring buffer can be used in either an overwrite mode or in
producer/consumer mode.
Producer/consumer mode is where the producer were to fill up the
Producer/consumer mode is where if the producer were to fill up the
buffer before the consumer could free up anything, the producer
will stop writing to the buffer. This will lose most recent events.
Overwrite mode is where the produce were to fill up the buffer
Overwrite mode is where if the producer were to fill up the buffer
before the consumer could free up anything, the producer will
overwrite the older data. This will lose the oldest events.
No two writers can write at the same time (on the same per cpu buffer),
No two writers can write at the same time (on the same per-cpu buffer),
but a writer may interrupt another writer, but it must finish writing
before the previous writer may continue. This is very important to the
algorithm. The writers act like a "stack". The way interrupts works
@ -88,7 +88,7 @@ A writer can preempt a reader, but a reader can not preempt a writer.
But a reader can read the buffer at the same time (on another processor)
as a writer.
The ring buffer is made up of a list of pages held together by a link list.
The ring buffer is made up of a list of pages held together by a linked list.
At initialization a reader page is allocated for the reader that is not
part of the ring buffer.
@ -102,7 +102,7 @@ the head page.
The reader has its own page to use. At start up time, this page is
allocated but is not attached to the list. When the reader wants
to read from the buffer, if its page is empty (like it is on start up)
to read from the buffer, if its page is empty (like it is on start-up),
it will swap its page with the head_page. The old reader page will
become part of the ring buffer and the head_page will be removed.
The page after the inserted page (old reader_page) will become the
@ -281,7 +281,7 @@ with the previous write.
The commit pointer points to the last write location that was
committed without preempting another write. When a write that
preempted another write is committed, it only becomes a pending commit
and will not be a full commit till all writes have been committed.
and will not be a full commit until all writes have been committed.
The commit page points to the page that has the last full commit.
The tail page points to the page with the last write (before
@ -292,7 +292,7 @@ be several pages ahead. If the tail page catches up to the commit
page then no more writes may take place (regardless of the mode
of the ring buffer: overwrite and produce/consumer).
The order of pages are:
The order of pages is:
head page
commit page
@ -395,7 +395,7 @@ The main idea behind the lockless algorithm is to combine the moving
of the head_page pointer with the swapping of pages with the reader.
State flags are placed inside the pointer to the page. To do this,
each page must be aligned in memory by 4 bytes. This will allow the 2
least significant bits of the address to be used as flags. Since
least significant bits of the address to be used as flags, since
they will always be zero for the address. To get the address,
simply mask out the flags.
@ -460,7 +460,7 @@ When the reader tries to swap the page with the ring buffer, it
will also use cmpxchg. If the flag bit in the pointer to the
head page does not have the HEADER flag set, the compare will fail
and the reader will need to look for the new head page and try again.
Note, the flag UPDATE and HEADER are never set at the same time.
Note, the flags UPDATE and HEADER are never set at the same time.
The reader swaps the reader page as follows:
@ -539,7 +539,7 @@ updated to the reader page.
| +-----------------------------+ |
+------------------------------------+
Another important point. The page that the reader page points back to
Another important point: The page that the reader page points back to
by its previous pointer (the one that now points to the new head page)
never points back to the reader page. That is because the reader page is
not part of the ring buffer. Traversing the ring buffer via the next pointers
@ -659,7 +659,7 @@ before pushing the head page. If it is, then it can be assumed that the
tail page wrapped the buffer, and we must drop new writes.
This is not a race condition, because the commit page can only be moved
by the outter most writer (the writer that was preempted).
by the outermost writer (the writer that was preempted).
This means that the commit will not move while a writer is moving the
tail page. The reader cannot swap the reader page if it is also being
used as the commit page. The reader can simply check that the commit
@ -733,7 +733,7 @@ The write converts the head page pointer to UPDATE.
--->| |<---| |<---| |<---| |<---
+---+ +---+ +---+ +---+
But if a nested writer preempts here. It will see that the next
But if a nested writer preempts here, it will see that the next
page is a head page, but it is also nested. It will detect that
it is nested and will save that information. The detection is the
fact that it sees the UPDATE flag instead of a HEADER or NORMAL
@ -892,7 +892,7 @@ It will return to the first writer.
--->| |<---| |<---| |<---| |<---
+---+ +---+ +---+ +---+
The first writer can not know atomically test if the tail page moved
The first writer cannot know atomically if the tail page moved
while it updates the HEAD page. It will then update the head page to
what it thinks is the new head page.
@ -923,9 +923,9 @@ if the tail page is either where it use to be or on the next page:
--->| |<---| |<---| |<---| |<---
+---+ +---+ +---+ +---+
If tail page != A and tail page does not equal B, then it must reset the
pointer back to NORMAL. The fact that it only needs to worry about
nested writers, it only needs to check this after setting the HEAD page.
If tail page != A and tail page != B, then it must reset the pointer
back to NORMAL. The fact that it only needs to worry about nested
writers means that it only needs to check this after setting the HEAD page.
(first writer)