-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathms_queue.h
More file actions
72 lines (63 loc) · 1.31 KB
/
ms_queue.h
File metadata and controls
72 lines (63 loc) · 1.31 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
72
#ifdef __APPLE__
#ifndef MS_QUEUE
#define MS_QUEUE
#include <iostream>
#include <atomic>
#define CAS compare_exchange_weak
#define DUMMY 0
using namespace std;
// implemented from lecture 31 slides
class msqueue {
public:
class node {
public:
node(int v):val(v){}
int val;
atomic<node*> next;
};
atomic<node*> head, tail;
msqueue();
void enqueue(int val, bool test);
int dequeue(bool test);
};
msqueue::msqueue() {
node *dummy = new node(DUMMY);
head.store(dummy);
tail.store(dummy);
}
void msqueue::enqueue(int value, bool test) {
node *t, *e, *n, *dummy = NULL;
n = new node(value);
while(true) {
t = tail.load();
e = t->next.load();
if(t == tail.load()) {
if(e == NULL && t->next.CAS(dummy,n)) break;
else if(e != NULL) tail.CAS(t,e);
}
}
if(test) printf("+%i ", n->val);
tail.CAS(t,n);
}
int msqueue::dequeue(bool test) {
node *t, *h, *n;
while(true) {
h = head.load();
t = tail.load();
n = h->next.load();
if(h == head.load()){
if(h == t){
if(n == NULL) return NULL;
else {tail.CAS(t,n);}
} else {
int ret = n->val;
if(head.CAS(h,n)) {
if(test) printf("-%i ", ret);
return ret;
}
}
}
}
}
#endif // MS_QUEUE
#endif // __APPLE__