You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+23-19Lines changed: 23 additions & 19 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -18,17 +18,18 @@ Pool ├── Stripe 0 (independent CAS machine)
18
18
```
19
19
20
20
Each stripe owns:
21
+
21
22
- Creation capacity
22
23
- Cached resources
23
24
- Waiter queues
24
25
- Cancellation tombstones
25
26
26
-
27
27
This ensures that threads never directly mutate shared structures, they instead:
28
-
1. Read immutable stripe state.
29
-
2. Compute a new immutable stripe.
30
-
3. CAS the old stripe, and replace with new stripe.
31
-
4. Execute deferred effects after commit.
28
+
29
+
1. Read immutable stripe state.
30
+
2. Compute a new immutable stripe.
31
+
3. CAS the old stripe, and replace with new stripe.
32
+
4. Execute deferred effects after commit.
32
33
33
34
All concurrent mutation is reduced to atomic replacement of immutable Stripe snapshots.
34
35
@@ -53,12 +54,12 @@ data Stripe a where
53
54
54
55
Most pool libraries spread state across the following:
55
56
56
-
-Semaphores
57
-
-Queues
58
-
-Thread state
59
-
-Mutable counters
60
-
-Exception handlers
61
-
-Background threads
57
+
- Semaphores
58
+
- Queues
59
+
- Thread state
60
+
- Mutable counters
61
+
- Exception handlers
62
+
- Background threads
62
63
63
64
This implementation instead centralizes everything into `Stripe a`, which makes the concurrency semantics **explicit** and **deterministic**. This is much closer to a distributed systems state machine or a lock-free runtime design than Haskell's [resource-pool](https://hackage.haskell.org/package/resource-pool) library.
64
65
@@ -80,9 +81,10 @@ record StripeStep a where
80
81
```
81
82
82
83
This separation is extremely important, as it enforces the boundary between CAS state machine transitions, and effects, which therefore prevents:
83
-
- Duplicated wakeups, frees and inserts
84
-
- Lost resources
85
-
- Retry corruption
84
+
85
+
- Duplicated wakeups, frees and inserts
86
+
- Lost resources
87
+
- Retry corruption
86
88
87
89
Below summarizes the general CAS transistion model flow:
88
90
@@ -165,6 +167,7 @@ When the cache is exhausted
165
167
## FIFO Queue Design
166
168
167
169
This library uses a two-list queue variant, `queue` and `queuer`, found in `Stripe a`:
170
+
168
171
-`queue` <-> front
169
172
-`queuer` <-> appended tail
170
173
@@ -174,9 +177,9 @@ In this model, `normalize` on `queue` and `queuer` produces the FIFO ordering.
174
177
175
178
Instead of mutating waiter nodes, the `cancelled` field (which is a `SortedSet Nat`) of `Stripe a` stores tombstones, which means:
176
179
177
-
-Waiters remain immutable.
178
-
-Queue structure remains immutable.
179
-
-Cancellation becomes monotonic state.
180
+
- Waiters remain immutable.
181
+
- Queue structure remains immutable.
182
+
- Cancellation becomes monotonic state.
180
183
181
184
## Cancellation State Machine
182
185
@@ -186,8 +189,8 @@ Instead of mutating waiter nodes, the `cancelled` field (which is a `SortedSet N
186
189
187
190
### Notes
188
191
189
-
-Cancellation does not remove queue nodes immediately.
190
-
-Cleanup occurs lazily during dequeue.
192
+
- Cancellation does not remove queue nodes immediately.
193
+
- Cleanup occurs lazily during dequeue.
191
194
192
195
### Why lazy cancellation matters
193
196
@@ -196,6 +199,7 @@ Correctness is much simpler due to avoiding immediate removal, instead we have i
196
199
### Core Cancellation Algorithm
197
200
198
201
`dequeueLive` is the core cancellation algorithm, as it:
0 commit comments