Skip to main content

arena_size_for

Function arena_size_for 

Source
pub const fn arena_size_for(cbs: usize) -> usize
Expand description

phase-271 — default arena bytes for a per-entry executor holding cbs callback slots. Scales the build-time ARENA_SIZE (which is sized for the default MAX_CBS) linearly by cbs, so a per-entry ExecutorSizing with a caller-chosen cbs gets the same per-slot arena budget the global default used — a fat entry (more callbacks) gets a larger arena, a lean one a smaller one — without a workspace-global NROS_EXECUTOR_ARENA_SIZE. Floored at the full default so no per-entry executor is ever smaller than a single-slot build would have been (the arena is a worst-case upper bound; over-provision is safe, under-provision fails entity creation).

§The ratio is for an UNDECLARED image only (issue 1290)

The scaling above reads ARENA_SIZE as a budget for MAX_CBS slots, so ARENA_SIZE / MAX_CBS is one slot’s worth and cbs of them is cbs slots’ worth. That is exactly what ARENA_SIZE is while nothing declared: the derivation budgets max_cbs worst-case entries plus a base overhead.

It stopped being that in phase-403 step 3 for an image that DECLARES its entities. There nros-node/build.rs sums the model per KIND — subscriptions at their own depth and type, timers at 64 bytes, services, action clients — and MAX_CBS is a separate knob that takes no part. Dividing by it then divides by a number with no relationship to the sum, and multiplying by cbs scales a total that was never per-slot. Measured on packages/testing/nros-bench/large-msg-baremetal with one declared subscription: the model is 14,424 bytes and arena_size_for(2) returned 7,212. Half.

So when the image declares, this asks the model: ARENA_SIZE IS the model (floored, and executor::arena_oracle refuses at compile time to let a stated knob sit below it), and every per-entry executor gets all of it.

That over-provisions a TIERED boot, where one tier holds a subset of the image and now carries the whole model. Deliberate, and the direction is the safe one: the alternative needs the ENTRY’s own per-kind counts where the macro emits the sizing, and those do not reach it today (issue 1290 records the choice). An entry that wants less states its own ExecutorSizing and holds it to what it registers with ExecutorSizing::assert_covers_model, which is a compile-time check the ratio never had.