]> AND Private Git Repository - loba.git/blob - sync_queue.h
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
357a72d8379a1c127b1499646fb4009aa18bf5a6
[loba.git] / sync_queue.h
1 #ifndef SYNC_QUEUE_H
2 #define SYNC_QUEUE_H
3
4 #if __GNUC__ == 4 && __GNUC_MINOR__ == 4
5 #  include <cstdatomic>         // <atomic> is named <cstdatomic> in gcc 4.4
6
7 template<typename _Tp>          // fix missing definition in gcc 4.4
8 void
9 atomic<_Tp*>::store(_Tp* __v, memory_order __m) volatile
10 { atomic_address::store(__v, __m); }
11
12 #else
13 #  include <atomic>
14 #endif
15
16 template <typename T>
17 class sync_queue {
18 public:
19     sync_queue()
20     {
21         node* n = new node(NULL);
22         head.store(n);
23         tail.store(n);
24     }
25
26     ~sync_queue()
27     {
28         node* n = head.load();
29         while (n != NULL) {
30             node* prev = n;
31             n = n->next;
32             delete prev;
33         }
34     }
35
36     bool empty() const
37     {
38         return head.load() == tail.load();
39     }
40
41     // size() is not not thread-safe
42     size_t size() const
43     {
44         size_t count = 0;
45         for (node* n = head.load()->next; n != NULL; n = n->next)
46             ++count;
47         return count;
48     }
49
50     bool push(const T& val)
51     {
52         node* old_tail = tail.load();
53         node* n = new node(val);
54         old_tail->next = n;
55         tail.store(n);
56         return (old_tail == head.load());
57     }
58
59     bool try_pop(T& res)
60     {
61         node* old_head = head.load();
62         if (old_head == tail.load()) { // empty?
63             return false;
64         } else {
65             node* new_head = old_head->next;
66             head.store(new_head);
67             delete old_head;
68             res = new_head->value;
69             return true;
70         }
71     }
72
73 private:
74     struct node {
75         node(const T& v): value(v), next(NULL) { }
76         T value;
77         node* next;
78     };
79
80     std::atomic<node*> head;
81     std::atomic<node*> tail;
82 };
83
84 #endif // !SYNC_QUEUE_H
85
86 // Local variables:
87 // mode: c++
88 // End: