1
- Backoff stack is an unbounded lock-free LIFO linked
2
- list, where pushes and pops synchronize at a single
3
- location. It is compare-and-set (CAS) atomic operation
4
- to provide concurrent access with obstruction freedom.
1
+ Elimination-backoff stack is an unbounded lock-free LIFO
2
+ linked list, that eliminates concurrent pairs of pushes
3
+ and pops with exchanges. It uses compare-and-set (CAS)
4
+ atomic operation to provide concurrent access with
5
+ obstruction freedom. In order to support even greater
6
+ concurrency, in case a push/pop fails, it tries to
7
+ pair it with another pop/push to eliminate the operation
8
+ through exchange of values.
5
9
6
10
``` java
7
11
push():
8
- 1. Create node for value.
9
- 2. Try pushing node to stack.
10
- 2a. If successful, return .
11
- 2b. Otherwise , backoff and try again.
12
+ 1. Create a new node with given value.
13
+ 2. Try pushing it to stack.
14
+ 3a. If successful, return.
15
+ 3b. Otherwise, try exchanging on elimination array.
16
+ 4a. If found a matching pop, return.
17
+ 4b. Otherwise, retry 2.
12
18
```
13
19
14
20
```java
15
21
pop():
16
22
1. Try popping a node from stack.
17
- 1a. If successful, return its value.
18
- 1b. Otherwise , backoff and try again.
23
+ 2a. If successful, return node' s value
24
+ 2b. Otherwise, try exchanging on elimination array.
25
+ 3a. If found a matching push, return its value.
26
+ 3b. Otherwise, retry 1.
19
27
```
20
28
21
29
```java
@@ -32,35 +40,56 @@ tryPop():
32
40
```
33
41
34
42
``` java
35
- backoff():
36
- 1. Get a random wait duration.
37
- 2. Sleep for the duration.
38
- 3. Double the max random wait duration.
43
+ EliminationArray . visit():
44
+ 1. Try exchanging value on a random exchanger.
45
+ ```
46
+
47
+ ``` java
48
+ Exchanger . exchange():
49
+ 1. Calculate last wait time.
50
+ 2. If wait time exceeded, then throw expection.
51
+ 3. Get slot value and stamp.
52
+ 4a. If slot is EMPTY (no value):
53
+ 4b. Try adding 1st value to slot, else retry 2.
54
+ 4c. Try getting 2nd value from slot, within time limit.
55
+ 5a. If slot is WAITING (has 1st value):
56
+ 5b. Try adding 2nd value to slot, else retry 2.
57
+ 5c. Return 1st value.
58
+ 6a. If slot is BUSY (has 2nd value):
59
+ 6b. Retry 2.
39
60
```
40
61
41
62
``` bash
42
63
# # OUTPUT
43
64
Starting 10 threads with sequential stack
44
- 1: failed pop
65
+ 4: failed push
66
+ 2: failed pop
45
67
3: failed pop
46
- 4: failed pop
47
- 1: popped 2/1000 values
48
- 1: has duplicate value 9999
49
- 1: has duplicate value 9998
50
- 3: popped 79/1000 values
51
- 3: has duplicate value 3761
52
- 4: popped 886/1000 values
68
+ 0: failed pop
69
+ 5: failed pop
70
+ 1: failed pop
71
+ 0: popped 346/1000 values
72
+ 1: popped 403/1000 values
73
+ 2: popped 1/1000 values
74
+ 2: has duplicate value 9881
75
+ 3: popped 6/1000 values
76
+ 3: has duplicate value 9654
77
+ 3: has duplicate value 9652
78
+ 4: popped 0/1000 values
79
+ 5: popped 6/1000 values
80
+ 5: has duplicate value 9359
81
+ 7: has duplicate value 9247
53
82
Was LIFO? false
54
83
55
- Starting 10 threads with backoff stack
84
+ Starting 10 threads with elimination backoff stack
56
85
Was LIFO? true
57
86
```
58
87
59
- See [BackoffStack .java] for code, [Main.java] for test, and [repl.it] for output.
88
+ See [ EliminationBackoffStack .java] for code, [ Main.java] for test, and [ repl.it] for output.
60
89
61
- [BackoffStack .java]: https://repl.it/@wolfram77/backoff-stack#BackoffStack .java
62
- [Main.java]: https://repl.it/@wolfram77/backoff-stack#Main.java
63
- [repl.it]: https://backoff-stack.wolfram77.repl.run
90
+ [ EliminationBackoffStack .java] : https://repl.it/@wolfram77/elimination- backoff-stack#EliminationBackoffStack .java
91
+ [ Main.java ] : https://repl.it/@wolfram77/elimination- backoff-stack#Main.java
92
+ [ repl.it ] : https://elimination- backoff-stack.wolfram77.repl.run
64
93
65
94
66
95
### references
0 commit comments