"Notes" loop buffers in the Linux kernel

Source: Internet
Author: User

1. Understanding of Ring Buffer

1) The ring buffer is the end-to-end buffer, which is similar to the life of the circular runway;

2) free space + data space =ring buffer size

3) ring buffer Read and write, similar to life in the round track Chase game, the leader bit write, chasing for read

4) If read runs too fast, catch up with Write, The Chaser read to stop, otherwise the game is over. That is, when there is no data space, the data is no longer read from the ring buffer;

5) If write runs too fast, in turn the ring is more than read, at which time the leader write will stop. That is to ensure that there is no free space, no longer write data into the ring buffer;

6) Therefore, the distance between read and write is always between open interval (0, buffer size)

2. linux2.6 Kernel, Kfifo understanding

Assume that the size of the buffer is sized, the read pointer is in, and the write pointer is out

1) in the computer, the integer data is added to the maximum value after the overflow will be rolled back to 0, starting from scratch)

2) The length of the buffer must be the N power of 2

3) Buffer free space and size of data space

1> the size of the free space =size-in+out

2> the size of the free space =in-out

2.2 Understanding of the calculation of data space size

This design always guarantees in front out front, in runs out unsigned int boundary overflow after the back volume.

Because the size of buffer is 2 of the power of N, and unsigned int is also the n power of 2 (32-bit machine, n=32), the general buffer size will not exceed the size of unsigned int, that is, unsigned int is divided into M-Whole block (m>=1)

1th Case:

out+ Data Space =in

Free space =size-Data Control =size-(in-out) =size-in+out

2nd case: (in run to unsigned int's boundary, overflow)

out+ data Space =in, this equation still holds.

So: Free space =size-in+out, also set up

2.3 Write operation analysis (read operation similar, no longer repeat)

2.3.1 Basic situation

Set to fall in the ring buffer, the write pointer is __in, the read pointer is __out, the space to write is Len, where

1. __in = fifo->in% (fifo->size-1) (read and write pointers starting from 0)

2. __out = fifo->out% (fifo->size-1)

3. __size = Fifo->size

4. Len <= free space size

2.3.2 Write pointer does not return volume

In this case, you need to write two buffer, do two copy action, set the size required to write Len, the first block of free space size is left1, the second block is left2, the first copy of the size of Len1, the second copy of the size of Len2,len1 + len2 = len:

1. left1 = _size-__in;

2. len1 = min (len, left1) = min (len, _size-__in);

3. left2 = __out;

4. Len2 = Len-len1

2.3.3 Write pointer back to volume

In this case, you need to write a buffer to do a copy action:

1. left1 = __out-__in <= __size-__in;

2. While writing length len <= free space size, len <= left1 <= __size-__in, so len1 = len, len1 = min (len, __size-__in) still set

3. left2 = 0;

4. Len2 = 0 = Len-len1

2.3.42 Special Cases Generalized

To summarize the above two cases, the first block of free space size is left1, the second block is left2, the first copy of the size is len1, the second copy is Len2,len1 + len2 = len, then the general situation is as follows:

1. Len <= free space size

2. len1 = min (len, _size-__in);

3. Len2 = Len-len1

Attached: linux2.6 kernel, KFIFO implementation code

Click (here) to collapse or open

  1. unsigned int __kfifo_put (struct Kfifo *fifo,
  2. unsigned char *buffer, unsigned int len)
  3. {
  4. unsigned int l;
  5. len = min (len, fifo->size-fifo->in + fifo->out);
  6. /* Precondition Write size len does not exceed free space size */
  7. SMP_MB ();
  8. /* The first block is written to the free space, the size is min (len, size-in) */
  9. L = min (len, Fifo->size-(Fifo->in & (Fifo->size-1)));
  10. memcpy (Fifo->buffer + (Fifo->in & (fifo->size-1)), buffer, L);
  11. /* The second block writes to the free space, size len-min (len, size-in) */
  12. memcpy (fifo->buffer, buffer + L, len-l);
  13. /*
  14. * Ensure that we add the bytes to the kfifo-before-
  15. * We update the fifo->in index.
  16. */
  17. SMP_WMB ();
  18. Fifo->in + = Len;
  19. return Len;
  20. }
  21. unsigned int __kfifo_get (struct Kfifo *fifo,
  22. unsigned char *buffer, unsigned int len)
  23. {
  24. unsigned int l;
  25. len = min (len, fifo->in-fifo->out);
  26. /*
  27. * Ensure that we sample the Fifo->in Index-before-we
  28. * Start removing bytes from the Kfifo.
  29. */
  30. SMP_RMB ();
  31. /* First get the data from Fifo->out until the end of the buffer */
  32. L = min (len, Fifo->size-(Fifo->out & (Fifo->size-1)));
  33. memcpy (buffer, Fifo->buffer + (Fifo->out & (Fifo->size-1)), L);
  34. /* Then get the rest (if any) from the beginning of the buffer */
  35. memcpy (buffer + L, Fifo->buffer, len-l);
  36. /*
  37. * Ensure that we remove the bytes from the kfifo-before-
  38. * We update the fifo->out index.
  39. */
  40. SMP_MB ();
  41. Fifo->out + = Len;
  42. return Len;
  43. }

"Notes" loop buffers in the Linux kernel

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.