GraphLab: Distributed Graph-Parallel API  2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
inplace_lf_queue.cpp
1 #include <graphlab/util/inplace_lf_queue.hpp>
2 namespace graphlab {
3 void inplace_lf_queue::enqueue(char* c) {
4  // clear the next pointer
5  (*get_next_ptr(c)) = NULL;
6  // atomically,
7  // swap(tail, c)
8  // tail->next = c;
9  char* prev = c;
10  atomic_exchange(tail, prev);
11  (*get_next_ptr(prev)) = c;
12  asm volatile ("" : : : "memory");
13 }
14 
15 
16 char* inplace_lf_queue::dequeue_all() {
17  // head is the sentinel
18  char* ret_head = get_next(head);
19  if (ret_head == NULL) return NULL;
20  // now, the sentinel is not actually part of the queue.
21  // by the time get_next(sentinel) is non-empty, enqueue must have completely
22  // finished at least once, since the next ptr is only connected in line 11.
23  // enqueue the sentinel. That will be the new head of the queue.
24  // Anything before the sentinel is "returned". And anything after is part
25  // of the queue
26  enqueue(sentinel);
27 
28  // The last element in the returned queue
29  // will point to the sentinel.
30  return ret_head;
31 }
32 
33 
34 
35 } // namespace graphlab