lfmpscq.c 858 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. #include "lfmpscq.h"
  2. #include "foundation/atomics.h"
  3. void mpscq_init(mpscq_t* self)
  4. {
  5. self->head = &self->stub;
  6. self->tail = &self->stub;
  7. self->stub.Next = 0;
  8. }
  9. int mpscq_push(mpscq_t *self, queue_node_t *n)
  10. {
  11. queue_node_t *prev;
  12. n->Next = 0;
  13. prev = nx_atomic_swap_pointer(n, (void * volatile *)&self->head);
  14. //(*)
  15. prev->Next = n;
  16. return prev!=&self->stub;
  17. }
  18. queue_node_t *mpscq_pop(mpscq_t *self)
  19. {
  20. queue_node_t* tail = self->tail;
  21. queue_node_t* next = tail->Next;
  22. queue_node_t* head;
  23. if (tail == &self->stub)
  24. {
  25. if (0 == next)
  26. return 0;
  27. self->tail = next;
  28. tail = next;
  29. next = next->Next;
  30. }
  31. if (next)
  32. {
  33. self->tail = next;
  34. return tail;
  35. }
  36. head = self->head;
  37. if (tail != head)
  38. return (queue_node_t *)1;
  39. mpscq_push(self, &self->stub);
  40. next = tail->Next;
  41. if (next)
  42. {
  43. self->tail = next;
  44. return tail;
  45. }
  46. return 0;
  47. }