Advertisement
Guest User

q3.h

a guest
Dec 12th, 2014
1,127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.39 KB | None | 0 0
  1. #include <stdint.h>
  2. #include <stdlib.h>
  3. #include <emmintrin.h>
  4.  
  5. #ifndef likely
  6. #define likely(x)       __builtin_expect((x), 1)
  7. #endif
  8.  
  9. #ifndef unlikely
  10. #define unlikely(x)     __builtin_expect((x), 0)
  11. #endif
  12.  
  13.  
  14. #define QSZ     (1024 * 1)
  15. #define QMSK    (QSZ - 1)
  16.  
  17. struct msg {
  18.         uint64_t dummy;
  19. };
  20.  
  21. #define CACHE_LINE_SIZE         64
  22.  
  23. struct queue {
  24.         struct {
  25.                 uint32_t mask;
  26.                 uint32_t size;
  27.                 volatile uint32_t head;
  28.                 volatile uint32_t tail;
  29.         } p;
  30.         char pad[CACHE_LINE_SIZE - 4 * sizeof(uint32_t)];
  31.  
  32.         struct {
  33.                 uint32_t mask;
  34.                 uint32_t size;
  35.                 volatile uint32_t head;
  36.                 volatile uint32_t tail;
  37.         } c;
  38.         char pad2[CACHE_LINE_SIZE - 4 * sizeof(uint32_t)];
  39.  
  40.         void              *msgs[0];
  41. };
  42.  
  43. static inline struct queue *
  44. qinit(void)
  45. {
  46.         struct queue *q = calloc(1, sizeof(*q) + QSZ * sizeof(void *));
  47.         q->p.size = q->c.size = QSZ;
  48.         q->p.mask = q->c.mask = QMSK;
  49.  
  50.         return q;
  51. }
  52.  
  53.  
  54. static inline int
  55. push(struct queue *q, void *m)
  56. {
  57.         uint32_t head, tail, mask, next;
  58.         int ok;
  59.  
  60.         mask = q->p.mask;
  61.  
  62.         do {
  63.                 head = q->p.head;
  64.                 tail = q->c.tail;
  65.                 if ((mask + tail - head) < 1U)
  66.                         return -1;
  67.                 next = head + 1;
  68.                 ok = __sync_bool_compare_and_swap(&q->p.head, head, next);
  69.         } while (!ok);
  70.  
  71.         q->msgs[head & mask] = m;
  72.         asm volatile ("":::"memory");
  73.  
  74.         while (unlikely((q->p.tail != head)))
  75.                 _mm_pause();
  76.  
  77.         q->p.tail = next;
  78.  
  79.         return 0;
  80. }
  81.  
  82. static inline void *
  83. pop(struct queue *q)
  84. {
  85.         uint32_t head, tail, mask, next;
  86.         int ok;
  87.         void *ret;
  88.  
  89.         mask = q->c.mask;
  90.  
  91.         do {
  92.                 head = q->c.head;
  93.                 tail = q->p.tail;
  94.                 if ((tail - head) < 1U)
  95.                         return NULL;
  96.                 next = head + 1;
  97.                 ok = __sync_bool_compare_and_swap(&q->c.head, head, next);
  98.         } while (!ok);
  99.  
  100.         ret = q->msgs[head & mask];
  101.         asm volatile ("":::"memory");
  102.  
  103.         while (unlikely((q->c.tail != head)))
  104.                 _mm_pause();
  105.  
  106.         q->c.tail = next;
  107.  
  108.         return ret;
  109. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement