ringbuffer.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /* The MIT License (MIT)
  2. *
  3. * Copyright (c) 2013 Philip Thrasher
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  6. * this software and associated documentation files (the "Software"), to deal in
  7. * the Software without restriction, including without limitation the rights to
  8. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  9. * the Software, and to permit persons to whom the Software is furnished to do so,
  10. * subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in all
  13. * copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  17. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  18. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  19. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  20. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. * Philip Thrasher's Crazy Awesome Ring Buffer Macros!
  22. *
  23. * Below you will find some naughty macros for easy owning and manipulating
  24. * generic ring buffers. Yes, they are slightly evil in readability, but they
  25. * are really fast, and they work great.
  26. *
  27. * Example usage:
  28. *
  29. * #include <stdio.h>
  30. *
  31. * // So we can use this in any method, this gives us a typedef
  32. * // named 'intBuffer'.
  33. * ringBuffer_typedef(int, intBuffer);
  34. *
  35. * int main() {
  36. * // Declare vars.
  37. * intBuffer myBuffer;
  38. *
  39. * bufferInit(myBuffer,1024,int);
  40. *
  41. * // We must have the pointer. All of the macros deal with the pointer.
  42. * // (except for init.)
  43. * intBuffer* myBuffer_ptr;
  44. * myBuffer_ptr = &myBuffer;
  45. *
  46. * // Write two values.
  47. * bufferWrite(myBuffer_ptr,37);
  48. * bufferWrite(myBuffer_ptr,72);
  49. *
  50. * // Read a value into a local variable.
  51. * int first;
  52. * bufferRead(myBuffer_ptr,first);
  53. * assert(first == 37); // true
  54. *
  55. * int second;
  56. * bufferRead(myBuffer_ptr,second);
  57. * assert(second == 72); // true
  58. *
  59. * return 0;
  60. * }
  61. *
  62. */
  63. #ifndef _ringbuffer_h
  64. #define _ringbuffer_h
  65. #define ringBuffer_typedef(T, NAME) \
  66. typedef struct { \
  67. int size; \
  68. volatile int start; \
  69. volatile int end; \
  70. T* elems; \
  71. } NAME
  72. #define bufferInit(BUF, S, T) \
  73. BUF.size = S+1; \
  74. BUF.start = 0; \
  75. BUF.end = 0; \
  76. BUF.elems = (T*)calloc(BUF.size, sizeof(T))
  77. #define bufferDestroy(BUF) free(BUF->elems)
  78. #define nextStartIndex(BUF) ((BUF->start + 1) % BUF->size)
  79. #define nextEndIndex(BUF) ((BUF->end + 1) % BUF->size)
  80. #define isBufferEmpty(BUF) (BUF->end == BUF->start)
  81. #define isBufferFull(BUF) (nextEndIndex(BUF) == BUF->start)
  82. #define bufferWrite(BUF, ELEM) \
  83. BUF->elems[BUF->end] = ELEM; \
  84. BUF->end = (BUF->end + 1) % BUF->size; \
  85. if (isBufferEmpty(BUF)) { \
  86. BUF->start = nextStartIndex(BUF); \
  87. }
  88. #define bufferRead(BUF, ELEM) \
  89. ELEM = BUF->elems[BUF->start]; \
  90. BUF->start = nextStartIndex(BUF);
  91. #endif