-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlf_queue.h
More file actions
71 lines (56 loc) · 1.42 KB
/
lf_queue.h
File metadata and controls
71 lines (56 loc) · 1.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#ifndef LF_QUEUE_H_
#define LF_QUEUE_H_
#include "atomic.h"
#include "atomic_ops.h"
template <typename T>
class lf_queue {
public:
inline lf_queue() : sentinel(NULL), head(NULL), tail(NULL) {
}
inline void init() {
sentinel = new T();
sentinel->next = NULL;
head = sentinel;
tail = sentinel;
}
static inline T *get_next(T *ptr) { return ptr->next; }
static inline T **get_next_ptr(T *ptr) { return &(ptr->next); }
~lf_queue() { delete sentinel; }
void enqueue(T *c) {
// c->next = NULL
// prev = c
// swap(prev, tail)
// prev->next = c
(*get_next_ptr(c)) = NULL;
// c->next = NULL;
T *prev = c;
atomic_exchange(tail, prev);
// prev->next = c;
(*get_next_ptr(prev)) = c;
// numel.inc();
asm volatile("" : : : "memory");
}
// size_t approx_size() { return numel.value; }
bool empty() const { return head->next == NULL; }
T *dequeue_all() {
// ret_head = head->next
// sentinel->next = NULL
// prev = sentinel
// swap(prev, tail)
// prev->next = sentinel
// numel = 0
T *ret_head = get_next(head);
if (ret_head == NULL) return NULL;
enqueue(sentinel);
// numel.exchange(0);
return ret_head;
}
T *end_of_dequeue_list() { return sentinel; }
inline const bool end_of_dequeue_list(T *ptr) { return ptr == (sentinel); }
private:
// atomic<size_t> numel;
T *sentinel;
T *head;
T *tail;
};
#endif