queue.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #include "os/queue.h"
  2. #include "os/co_task.h"
  3. typedef struct {
  4. u8 * buffer;
  5. int16_t count;
  6. int16_t esize;
  7. int16_t w_pos;
  8. int16_t r_pos;
  9. }queue_t;
  10. static __inline__ bool _have_write_space(queue_t *queue){
  11. int16_t buffer_len = queue->count * queue->esize;
  12. int16_t size = (queue->w_pos >= queue->r_pos)?(buffer_len - queue->w_pos + queue->r_pos):(queue->r_pos - queue->w_pos);
  13. size -= queue->esize;
  14. if (size <= 0){
  15. return false;
  16. }
  17. return true;
  18. }
  19. static __inline__ bool _have_read_space(queue_t *queue){
  20. int16_t buffer_len = queue->count * queue->esize;
  21. int16_t size = (queue->r_pos > queue->w_pos) ? (buffer_len - queue->r_pos + queue->w_pos) : (queue->w_pos - queue->r_pos);
  22. if (size < queue->esize){
  23. return false;
  24. }
  25. return true;
  26. }
  27. void *queue_create(u16 queue_count, u16 esize){
  28. queue_t *queue = (queue_t *)co_malloc(queue_count * esize + sizeof(queue_t));
  29. if (queue == NULL) {
  30. return NULL;
  31. }
  32. queue->buffer = (u8 *)(queue + 1);
  33. queue->count = queue_count;
  34. queue->esize = esize;
  35. queue->w_pos = queue->r_pos = 0;
  36. return queue;
  37. }
  38. bool queue_put(co_queue_t vqueue, void *data){
  39. queue_t *queue = (queue_t *)vqueue;
  40. os_disable_irq();
  41. if (!_have_write_space(queue)){
  42. os_enable_irq();
  43. return false;
  44. }
  45. memcpy(queue->buffer + queue->w_pos, data, queue->esize);
  46. queue->w_pos = queue->w_pos + queue->esize;
  47. if (queue->w_pos == queue->count * queue->esize){
  48. queue->w_pos = 0;
  49. }
  50. os_enable_irq();
  51. return true;
  52. }
  53. bool queue_get(co_queue_t vqueue, void *data) {
  54. queue_t *queue = (queue_t *)vqueue;
  55. os_disable_irq();
  56. if(!_have_read_space(queue)){
  57. os_enable_irq();
  58. return false;
  59. }
  60. if (data) {
  61. memcpy(data, queue->buffer + queue->r_pos, queue->esize);
  62. }
  63. queue->r_pos = queue->r_pos + queue->esize;
  64. if (queue->r_pos == queue->count * queue->esize){
  65. queue->r_pos = 0;
  66. }
  67. os_enable_irq();
  68. return true;
  69. }