Skip to content

Commit 73ec0e7

Browse files
Addressing linting again with markdownlint-cli2.
1 parent f21d9b9 commit 73ec0e7

1 file changed

Lines changed: 23 additions & 19 deletions

File tree

README.md

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,18 @@ Pool ├── Stripe 0 (independent CAS machine)
1818
```
1919

2020
Each stripe owns:
21+
2122
- Creation capacity
2223
- Cached resources
2324
- Waiter queues
2425
- Cancellation tombstones
2526

26-
2727
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.
3233

3334
All concurrent mutation is reduced to atomic replacement of immutable Stripe snapshots.
3435

@@ -53,12 +54,12 @@ data Stripe a where
5354

5455
Most pool libraries spread state across the following:
5556

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
6263

6364
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.
6465

@@ -80,9 +81,10 @@ record StripeStep a where
8081
```
8182

8283
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
8688

8789
Below summarizes the general CAS transistion model flow:
8890

@@ -165,6 +167,7 @@ When the cache is exhausted
165167
## FIFO Queue Design
166168

167169
This library uses a two-list queue variant, `queue` and `queuer`, found in `Stripe a`:
170+
168171
- `queue` <-> front
169172
- `queuer` <-> appended tail
170173

@@ -174,9 +177,9 @@ In this model, `normalize` on `queue` and `queuer` produces the FIFO ordering.
174177

175178
Instead of mutating waiter nodes, the `cancelled` field (which is a `SortedSet Nat`) of `Stripe a` stores tombstones, which means:
176179

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.
180183

181184
## Cancellation State Machine
182185

@@ -186,8 +189,8 @@ Instead of mutating waiter nodes, the `cancelled` field (which is a `SortedSet N
186189

187190
### Notes
188191

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.
191194

192195
### Why lazy cancellation matters
193196

@@ -196,6 +199,7 @@ Correctness is much simpler due to avoiding immediate removal, instead we have i
196199
### Core Cancellation Algorithm
197200

198201
`dequeueLive` is the core cancellation algorithm, as it:
202+
199203
1. Pop queue head
200204
2. Check tombstone set
201205
3. If cancelled:

0 commit comments

Comments
 (0)