fifo.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #include "fifo.h"
  2. #include <string.h>
  3. #ifdef SALOF_USING_LOG
  4. static unsigned int _flbs(unsigned int x) /* find last bit set*/
  5. {
  6. unsigned int r = 32;
  7. if (!x)
  8. return 0;
  9. if (!(x & 0xffff0000u)) {
  10. x <<= 16;
  11. r -= 16;
  12. }
  13. if (!(x & 0xff000000u)) {
  14. x <<= 8;
  15. r -= 8;
  16. }
  17. if (!(x & 0xf0000000u)) {
  18. x <<= 4;
  19. r -= 4;
  20. }
  21. if (!(x & 0xc0000000u)) {
  22. x <<= 2;
  23. r -= 2;
  24. }
  25. if (!(x & 0x80000000u)) {
  26. x <<= 1;
  27. r -= 1;
  28. }
  29. return r;
  30. }
  31. static unsigned int _salof_fifo_align(unsigned int x)
  32. {
  33. return (1 << (_flbs(x-1)-1)); //memory down alignment
  34. }
  35. salof_fifo_t salof_fifo_create(unsigned int size)
  36. {
  37. salof_fifo_t fifo;
  38. if (0 == size)
  39. return NULL;
  40. if (size & (size - 1))
  41. size = _salof_fifo_align(size);
  42. fifo = (salof_fifo_t)salof_alloc((sizeof(struct salof_fifo) + size));
  43. if (NULL != fifo) {
  44. fifo->buff = (unsigned char *)fifo + sizeof(struct salof_fifo);
  45. fifo->mutex = salof_mutex_create();
  46. fifo->sem = salof_sem_create();
  47. if ((NULL == fifo->mutex) || (NULL == fifo->sem)) {
  48. salof_free(fifo);
  49. return NULL;
  50. }
  51. fifo->size = size;
  52. fifo->in = 0;
  53. fifo->out = 0;
  54. return fifo;
  55. }
  56. return NULL;
  57. }
  58. unsigned int salof_fifo_write(salof_fifo_t fifo, void *buff, unsigned int len, unsigned int timeout)
  59. {
  60. int err, l;
  61. if((!fifo) || (!buff) || (!len))
  62. return 0;
  63. err = salof_mutex_pend(fifo->mutex, timeout);
  64. if(err == -1)
  65. return 0;
  66. len = FIFO_MIN(len, (fifo->size - fifo->in + fifo->out));
  67. l = FIFO_MIN(len, (fifo->size - (fifo->in & (fifo->size -1))));
  68. memcpy(((unsigned char *)fifo->buff + (fifo->in & (fifo->size -1))), buff, l);
  69. memcpy(fifo->buff, (unsigned char *)buff + l, len - l);
  70. fifo->in += len;
  71. salof_mutex_post(fifo->mutex);
  72. salof_sem_post(fifo->sem);
  73. return len;
  74. }
  75. unsigned int salof_fifo_read(salof_fifo_t fifo, void *buff, unsigned int len, unsigned int timeout)
  76. {
  77. int l;
  78. salof_sem_pend(fifo->sem, timeout);
  79. if((!fifo) || (!buff) || (!len))
  80. return 0;
  81. len = FIFO_MIN(len, fifo->in - fifo->out);
  82. l = FIFO_MIN(len, (fifo->size - (fifo->out & (fifo->size -1))));
  83. memcpy(buff, ((unsigned char *)fifo->buff + (fifo->out & (fifo->size -1))), l);
  84. memcpy((unsigned char *)buff + l, fifo->buff, len - l);
  85. fifo->out += len;
  86. return len;
  87. }
  88. unsigned int salof_fifo_read_able(salof_fifo_t fifo)
  89. {
  90. if(NULL == fifo)
  91. return 0;
  92. else if(fifo->in == fifo->out)
  93. return 0;
  94. else if(fifo->in > fifo->out)
  95. return (fifo->in - fifo->out);
  96. return (fifo->size - (fifo->out - fifo->in));
  97. }
  98. unsigned int salof_fifo_write_able(salof_fifo_t fifo)
  99. {
  100. return (fifo->size - salof_fifo_read_able(fifo));
  101. }
  102. #endif