ringbuffer.h 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /* Philip Thrasher's Crazy Awesome Ring Buffer Macros!
  2. *
  3. * Below you will find some naughty macros for easy owning and manipulating
  4. * generic ring buffers. Yes, they are slightly evil in readability, but they
  5. * are really fast, and they work great.
  6. *
  7. * Example usage:
  8. *
  9. * #include <stdio.h>
  10. *
  11. * // So we can use this in any method, this gives us a typedef
  12. * // named 'intBuffer'.
  13. * ringBuffer_typedef(int, intBuffer);
  14. *
  15. * int main() {
  16. * // Declare vars.
  17. * intBuffer myBuffer;
  18. *
  19. * bufferInit(myBuffer,1024,int);
  20. *
  21. * // We must have the pointer. All of the macros deal with the pointer.
  22. * // (except for init.)
  23. * intBuffer* myBuffer_ptr;
  24. * myBuffer_ptr = &myBuffer;
  25. *
  26. * // Write two values.
  27. * bufferWrite(myBuffer_ptr,37);
  28. * bufferWrite(myBuffer_ptr,72);
  29. *
  30. * // Read a value into a local variable.
  31. * int first;
  32. * bufferRead(myBuffer_ptr,first);
  33. * assert(first == 37); // true
  34. *
  35. * int second;
  36. * bufferRead(myBuffer_ptr,second);
  37. * assert(second == 72); // true
  38. *
  39. * return 0;
  40. * }
  41. *
  42. */
  43. #ifndef _ringbuffer_h
  44. #define _ringbuffer_h
  45. int __mod(int a, int b)
  46. {
  47. int r = a % b;
  48. return r < 0 ? r + b : r;
  49. }
  50. #define ringBuffer_typedef(T, NAME) \
  51. typedef struct { \
  52. int size; \
  53. int start; \
  54. int end; \
  55. T* elems; \
  56. } NAME
  57. #define bufferInit(BUF, S, T) \
  58. BUF.size = S+1; \
  59. BUF.start = 0; \
  60. BUF.end = 0; \
  61. BUF.elems = (T*)calloc(BUF.size, sizeof(T))
  62. #define bufferDestroy(BUF) free(BUF->elems)
  63. #define nextStartIndex(BUF) ((BUF->start + 1) % BUF->size)
  64. #define nextEndIndex(BUF) ((BUF->end + 1) % BUF->size)
  65. #define isBufferEmpty(BUF) (BUF->end == BUF->start)
  66. #define isBufferFull(BUF) (nextEndIndex(BUF) == BUF->start)
  67. #define bufferGet(BUF, INDEX) (BUF->elems[__mod(BUF->end - INDEX, BUF->size)])
  68. #define bufferWrite(BUF, ELEM) \
  69. BUF->elems[BUF->end] = ELEM; \
  70. BUF->end = (BUF->end + 1) % BUF->size; \
  71. if (isBufferEmpty(BUF)) { \
  72. BUF->start = nextStartIndex(BUF); \
  73. }
  74. #define bufferRead(BUF, ELEM) \
  75. ELEM = BUF->elems[BUF->start]; \
  76. BUF->start = nextStartIndex(BUF);
  77. #endif