2
2
import java .util .concurrent .*;
3
3
import java .util .concurrent .atomic .*;
4
4
5
+ // Elimination-backoff stack is an unbounded lock-free LIFO linked list, that eliminates concurrent pairs of pushes and pops with exchanges.
5
6
6
7
class EliminationBackoffStack <T > {
7
8
AtomicReference <Node <T >> top ;
8
9
EliminationArray <T > eliminationArray ;
9
- static final int CAPACITY = 1 ;
10
+ static final int CAPACITY = 100 ;
11
+ static final long TIMEOUT = 10 ;
12
+ static final TimeUnit UNIT = TimeUnit .MILLISECONDS ;
10
13
static ThreadLocal <RangePolicy > policy = new ThreadLocal <>() {
11
14
protected RangePolicy initialValue () {
12
15
return new RangePolicy (CAPACITY );
13
16
}
14
17
};
18
+ // top: top of stack (null if empty)
19
+ // eliminationArray: for exchanging values between push, pop
20
+ // CAPACITY: capacity of elimination array
21
+ // TIMEOUT: exchange timeout for elimination array
22
+ // UNIT: exchange timeout unit for elimination array
23
+ // policy: strategy for in use range of elimination array
15
24
16
25
public EliminationBackoffStack () {
17
26
top = new AtomicReference <>(null );
18
- eliminationArray = new EliminationArray <>(CAPACITY );
27
+ eliminationArray = new EliminationArray <>(CAPACITY , TIMEOUT , UNIT );
19
28
}
20
29
30
+ // 1. Create a new node with given value.
31
+ // 2. Try pushing it to stack.
32
+ // 3a. If successful, return.
33
+ // 3b. Otherwise, try exchanging on elimination array.
34
+ // 4a. If exchange failed to find a pop, retry 2.
35
+ // 4b. Otherwise, record success and return.
36
+ // 4c. If timeout ocurred, record it.
21
37
public void push (T x ) {
22
38
RangePolicy p = policy .get ();
23
39
Node <T > n = new Node <>(x );
@@ -32,17 +48,23 @@ public void push(T x) {
32
48
}
33
49
}
34
50
51
+ // 1. Try popping a node from stack.
52
+ // 2a. If successful, return node's value
53
+ // 2b. Otherwise, try exchanging on elimination array.
54
+ // 3a. If exchange failed to find a push, retry 1.
55
+ // 3b. Otherwise, return paired push value.
56
+ // 3c. If timeout occurred, record it.
35
57
public T pop () throws EmptyStackException {
36
58
RangePolicy p = policy .get ();
37
59
while (true ) {
38
- Node <T > n = tryPop ();
39
- if (n != null ) return n .value ;
60
+ Node <T > n = tryPop (); // 1
61
+ if (n != null ) return n .value ; // 2a
40
62
try {
41
- T y = eliminationArray .visit (null , p .range ());
42
- if (y == null ) continue ;
43
- p .onSuccess (); return y ;
63
+ T y = eliminationArray .visit (null , p .range ()); // 2b
64
+ if (y == null ) continue ; // 3a
65
+ p .onSuccess (); return y ; // 3b
44
66
}
45
- catch (TimeoutException e ) { p .onTimeout (); }
67
+ catch (TimeoutException e ) { p .onTimeout (); } // 3c
46
68
}
47
69
}
48
70
0 commit comments