Set resource budgets.

Bound application-owned resources, apply deadlines at operation boundaries, and place checkpoints in cooperative CPU work.

STEP 09

Bound application-owned resources.

No single value defines an application capacity plan. Bound each resource that the application owns and set latency limits at operation boundaries. Then measure the complete configuration under representative peak load.

Concurrency
Use a structured server or Connections.Server capacity to limit owned connections. A structured server creates exactly Capacity handler tasks for the complete Serve operation, including idle periods.
Stack memory
For homogeneous lightweight tasks, multiply peak live tasks by the measured effective bytes per task. Use Reserved_Bytes for guarded virtual address space. Measure RSS for resident memory.
Task-owned regions
Region storage grows on demand and has no built-in quota. Limit the number and size of admitted phases. Sample Statistics and call Release at the earliest valid lifetime boundary.
Dormant stacks
Choose Minimum_Wait from tolerated wake latency and representative host measurements. Accepted cold or page-out advice does not reduce the configured stack capacity.
Parallelism
FLYOLOGY_LOOP_POOL_SIZE selects the initial automatic shared groups, not the task count. Start near the usable CPU parallelism of the workload. Grow with Grow_Configured_Pool when measurements support the change. Each created group adds an OS thread, poller, scheduler, and kernel-queue resources.
Latency
Use finite I/O deadlines, a bounded shutdown drain, and checkpoints in CPU loops. These controls are separate. Cancellation is not a timeout. A fairness quantum is not a hard execution deadline.

Bound admission, not just the listen backlog

The structured-server capacity limits active handlers and reserves the handler task resources. Excess work remains in the kernel listen backlog. It does not create an unbounded user-space task or connection queue.

bounded structured service
Handler_Capacity : constant Positive := 256;

Server : aliased HTTP.Server (Capacity => Handler_Capacity);

HTTP.Serve
  (Server, Listener, State, Drain_Timeout => 5.0);

Use one deadline for the complete operation

Receive_Exactly and Send_All apply one timeout to the complete multi-step operation. Partial transfers do not restart the timeout. DNS resolution also applies one timeout to family queries, retry rounds, and transport fallback.

Prefer finite deadlines at service boundaries. If the scope does not have an explicit shutdown and cancellation path, do not use Infinite.

Add checkpoints to bounded units of CPU work

A CPU-bound lightweight task can occupy its group until it suspends, executes delay 0.0, or calls a fairness checkpoint. Priorities select among ready fibers in a group, but they do not preempt arbitrary lightweight instructions.

A new Yield_Budget uses a 2 ms quantum. Configure a different quantum when the service requires a different cooperative interval.

time-budgeted fairness
Budget : Flyology.Fairness.Yield_Budget;

Budget.Configure (Ada.Real_Time.Microseconds (250));
while More_Work loop
   Process_One_Item;
   Budget.Checkpoint;
end loop;

Choose a quantum below the tolerated same-group scheduling delay, then measure it. The value is elapsed wall-clock time between eligible yields, not reserved CPU time.

Put Checkpoint after a bounded unit of work. For example, a 250 µs quantum cannot interrupt a Process_One_Item call that runs for 50 ms. The checkpoint takes effect after the call returns. Very small quanta also increase clock reads and scheduler transfers.