190fddabf5818367c6bd1fe1b256a10e01827862fDavid Howells/*
290fddabf5818367c6bd1fe1b256a10e01827862fDavid Howells * See Documentation/circular-buffers.txt for more information.
390fddabf5818367c6bd1fe1b256a10e01827862fDavid Howells */
490fddabf5818367c6bd1fe1b256a10e01827862fDavid Howells
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef _LINUX_CIRC_BUF_H
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define _LINUX_CIRC_BUF_H 1
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct circ_buf {
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *buf;
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int head;
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int tail;
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Return count in buffer.  */
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CIRC_CNT(head,tail,size) (((head) - (tail)) & ((size)-1))
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Return space available, 0..size-1.  We always leave one free char
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   as a completely full buffer has head == tail, which is the same as
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   empty.  */
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CIRC_SPACE(head,tail,size) CIRC_CNT((tail),((head)+1),(size))
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Return count up to the end of the buffer.  Carefully avoid
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   accessing head and tail more than once, so they can change
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   underneath us without returning inconsistent results.  */
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CIRC_CNT_TO_END(head,tail,size) \
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	({int end = (size) - (tail); \
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	  int n = ((head) + end) & ((size)-1); \
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	  n < end ? n : end;})
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Return space available up to the end of the buffer.  */
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CIRC_SPACE_TO_END(head,tail,size) \
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	({int end = (size) - 1 - (head); \
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	  int n = (end + (tail)) & ((size)-1); \
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	  n <= end ? n : end+1;})
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* _LINUX_CIRC_BUF_H  */
37