1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
//! Concurrency primitives for the async CFR exploration engine.
use Arc;
use Semaphore;
/// Cap on concurrently in-flight `compute_reward` tasks.
///
/// A single limiter instance is passed down through every level of one agent's
/// exploration, so that agent's recursive spawning composes to one bound
/// rather than multiplying with depth. Spawning is gated by `try_acquire`:
/// when no permit is free, a branch runs inline instead of spawning, which
/// keeps recursion deadlock-free at any depth.
///
/// The bound is per limiter instance, not process-wide. `build_default_limiter()`
/// allocates a fresh semaphore, so distinct agents — and the competition
/// runner — each get their own unless a caller deliberately shares one
/// `Arc<Semaphore>` across them (see `CFRAgentBuilder::limiter`).
pub type InFlightLimiter = ;
/// Default in-flight permit count: `8 × available parallelism` (minimum 8).
///
/// Sized above the core count on purpose: the runtime's worker threads already
/// bound CPU parallelism, so this cap mainly governs memory when CPU-bound and,
/// once ML inference lands, how many subtree walkers can park at inference
/// awaits to feed batches. Exposed as a separate seam so a future
/// `LimiterConfig` can override it without touching call sites.
/// Build a fresh limiter sized at [`default_limiter_permits`].
///
/// Builds (does not share) a new `Arc<Semaphore>`; distinct agents each get
/// their own bound unless a caller deliberately shares one (see
/// `CFRAgentBuilder::limiter`).