0 | ||| Resource Pool Internals
12 | %language ElabReflection
16 | ||| Configuration of a Pool.
17 | |||
18 | ||| Constraints:
19 | ||| - poolmaxresources -> The smallest acceptable value is 1.
20 | ||| - poolnumstripes -> The smallest acceptable value is 1, poolnumstripes must not be larger than poolmaxresources.
21 | |||
32 | ||| A simple (persistent) FIFO queue.
33 | |||
34 | ||| This is used to maintain an ordered collection of waiting threads.
35 | ||| Elements are appended at the tail and removed from the head.
36 | |||
37 | ||| Notes:
38 | ||| - This representation has O(n) append.
39 | ||| - Under contention (with CAS updates), appends may be retried, so this structure favors simplicity over performance.
40 | ||| - It is typically used together with a secondary "reversed" queue to amortize costs (two-list queue pattern).
41 | |||
47 | ||| Result of waking a waiting thread.
48 | |||
49 | ||| This represents the outcome delivered to a blocked waiter through its wake channel.
50 | |||
51 | ||| Variants:
52 | ||| - `Deliver a`
53 | ||| - A resource was directly handed off to the waiter.
54 | |||
55 | ||| - `Create`
56 | ||| - No reusable resource was available, but the waiter should proceed by creating a fresh resource using an already-reserved capacity slot.
57 | |||
58 | ||| - `Cancelled`
59 | ||| - The waiter was cancelled before receiving a resource.
60 | ||| - This is used to distinguish cancellation from normal wakeup semantics.
61 | |||
62 | ||| Design Notes:
63 | ||| - This replaces the older `Maybe a` wake protocol, which overloaded `Nothing` to represent multiple meanings.
64 | ||| - Explicit wake states improve clarity and correctness of the Stripe state machine.
65 | |||
66 | ||| Guarantees:
67 | ||| - Each waiter receives at most one `WakeResult`.
68 | ||| - Wake results correspond only to committed Stripe transitions.
69 | ||| - No wake result is delivered more than once.
70 | |||
71 | ||| Invariants:
72 | ||| - `Deliver a` carries ownership transfer of exactly one resource.
73 | ||| - `Create` implies capacity has already been reserved.
74 | ||| - `Cancelled` does not transfer ownership of a resource.
75 | |||
82 | ||| A pure waiting token representing a blocked thread.
83 | |||
84 | ||| This contains no mutable state. All lifecycle tracking is handled
85 | ||| by the Stripe during dequeue / cancellation.
86 | |||
87 | ||| Fields:
88 | ||| - `id` : unique identifier for cancellation tracking
89 | ||| - `wake` : channel used to unblock the thread
90 | |||
91 | ||| Invariants:
92 | ||| - Waiter is immutable
93 | ||| - Wake is single-use
94 | ||| - Cancellation is handled by Stripe (not locally)
95 | |||
102 | ||| An existing resource currently sitting in a pool.
103 | |||
110 | ||| Stripe is the only concurrent state machine in the system.
111 | |||
112 | ||| It owns:
113 | ||| - Resource availability.
114 | ||| - Cached resources.
115 | ||| - All waiting threads.
116 | ||| - Cancellation tracking.
117 | |||
118 | ||| All mutations occur via CAS on an enclosing Ref, `Stripe1 s a`.
119 | |||
120 | ||| Fields:
121 | ||| - `available` : number of available resources
122 | ||| - `cache` : reusable resources
123 | ||| - `queue` : primary FIFO of waiters
124 | ||| - `queuer` : secondary FIFO (amortized append)
125 | ||| - `nextId` : fresh waiter id supply
126 | ||| - `cancelled` : sorted set of cancelled waiter ids
127 | |||
128 | ||| Invariants:
129 | ||| - Stripe is immutable between CAS updates.
130 | ||| - Queue ordering is authoritative.
131 | ||| - Cancelled waiters are lazily skipped.
132 | |||
143 | ||| A linear mutable stripe.
144 | |||
150 | ||| Effects emitted by a Stripe transition.
151 | |||
152 | ||| These are collected during CAS computation and executed
153 | ||| only after a successful CAS commit.
154 | |||
155 | ||| Guarantees:
156 | ||| - No IO inside CAS.
157 | ||| - No duplicated effects on retry.
158 | ||| - Deterministic state transitions.
159 | |||
168 | ||| Result of a Stripe state transition.
169 | |||
170 | ||| Represents:
171 | ||| - The new Stripe state (to be CAS'd).
172 | ||| - Effects to run AFTER successful commit.
173 | |||
174 | ||| Invariants:
175 | ||| - This must be treated as a one-shot value.
176 | ||| - If CAS fails, this MUST be discarded.
177 | ||| - Effects must NEVER be run unless CAS succeeds.
178 | |||
185 | ||| A single, local pool based on a linear mutable stripe.
186 | |||
193 | ||| Striped resource pool based on linear mutable references.
194 | |||