blob: 3f8598629b4e95c561b5690cf22e44c453c03127 (
plain)
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
|
/*
* Interrupt transparent queue, Schoen et. al, "On Interrupt-Transparent
* Synchronization in an Embedded Object-Oriented Operating System", 2000.
* enqueue() is allowed to interrupt enqueue() and dequeue(), however,
* dequeue() is not allowed to interrupt itself.
*/
#include "../globals.h"
#include "lock_free_queue.h"
lock_free_queue_node::lock_free_queue_node() : next(NULL) {
}
lock_free_queue::lock_free_queue() : _tail(this) {
}
void
lock_free_queue::enqueue(lock_free_queue_node *item) {
lock.lock();
item->next = (lock_free_queue_node *) NULL;
lock_free_queue_node *last = _tail;
_tail = item;
while (last->next) {
last = last->next;
}
last->next = item;
lock.unlock();
}
lock_free_queue_node *
lock_free_queue::dequeue() {
lock.lock();
lock_free_queue_node *item = next;
if (item && !(next = item->next)) {
_tail = (lock_free_queue_node *) this;
if (item->next) {
lock_free_queue_node *lost = item->next;
lock_free_queue_node *help;
do {
help = lost->next;
enqueue(lost);
} while ((lost = help) != (lock_free_queue_node *) NULL);
}
}
lock.unlock();
return item;
}
bool
lock_free_queue::is_empty() {
return next == NULL;
}
|