Advertisement
Guest User

q.h

a guest
Dec 12th, 2014
415
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.74 KB | None | 0 0
  1. #include <stdint.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5.  
  6. struct msg {
  7.         struct msg *next;
  8. };
  9.  
  10. struct queue {
  11.         uint32_t head;
  12.         uint32_t tail;
  13.         struct msg      **msgs;
  14.         struct msg      *list;
  15. };
  16.  
  17. #define CNT     0x10000
  18. #define GP(x)   (x % (CNT))
  19.  
  20. static inline struct queue *
  21. qinit(void)
  22. {
  23.         struct queue *q = malloc(sizeof(*q));
  24.  
  25.         bzero(q, sizeof(*q));
  26.         q->msgs = calloc(sizeof(struct msg *), CNT);
  27.  
  28.         return q;
  29. }
  30.  
  31. static inline int
  32. push(struct queue *q, struct msg *m)
  33. {
  34.         uint32_t tail = GP(__sync_fetch_and_add(&q->tail, 1));
  35.  
  36.         if (!__sync_bool_compare_and_swap(&q->msgs[tail], NULL, m)) {
  37.                 struct msg *last;
  38.                 do {
  39.                         last = q->list;
  40.                         m->next = last;
  41.                 } while (!__sync_bool_compare_and_swap(&q->list, last, m));
  42.         }
  43.         return 0;
  44. }
  45.  
  46. static inline struct msg *
  47. pop(struct queue *q)
  48. {
  49.         uint32_t head = q->head;
  50.         uint32_t h2;
  51.         struct msg *list;
  52.  
  53.         if (head == q->tail)
  54.                 return NULL;
  55.  
  56.         h2 = GP(head);
  57.         list = q->list;
  58.  
  59.         if (list) {
  60.                 struct msg *n = list->next;
  61.                 if (__sync_bool_compare_and_swap(&q->list, list, n)) {
  62.                         list->next = NULL;
  63.                         push(q, list);
  64.                 }
  65.         }
  66.         struct msg *m = q->msgs[h2];
  67.         if (!m)
  68.                 return NULL;
  69.         if (!__sync_bool_compare_and_swap(&q->head, head, head + 1))
  70.                 return NULL;
  71.         if (!__sync_bool_compare_and_swap(&q->msgs[h2], m, NULL))
  72.                 return NULL;
  73.  
  74.         return m;
  75. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement