Choose an execution group.

Choose automatic placement or a shared or dedicated group. Migrate lightweight tasks only at explicit safe points.

STEP 07

Select placement and ownership.

Flyology places a task designated with Flyology.Lightweight_Task into the shared pool by deterministic round robin when it has no specific Ada CPU. A positive CPU aspect selects an exact execution group. Ada reserves CPU => 0 as Not_A_Specific_CPU. Therefore, zero has the same effect as an absent aspect.

explicit shared groups
task Parser with CPU => 1 is
   pragma Task_Info (Flyology.Lightweight_Task);
end Parser;

task Writer with CPU => 2 is
   pragma Task_Info (Flyology.Lightweight_Task);
end Writer;

Tasks in one group share a stable event-loop thread and schedule cooperatively. Separate groups use separate OS threads and can execute in parallel. Shared group identifiers are 0 .. 127. Dedicated group identifiers are 128 .. 255.

Grow the automatic pool later

Grow_Configured_Pool sets a minimum number of groups in the automatic pool. When no reduction is active, concurrent calls converge on the largest request, and calls at or below the current size have no effect. Existing tasks stay in their current groups, while future automatic placements use the larger pool. Growth alone starts no group or OS thread.

grow runtime configuration
Flyology.Execution_Groups.Grow_Configured_Pool (8);

A growth request raises Group_Error while a pool reduction still has blockers. Blockers are automatic tasks or placement claims that started before the cutover.

The growth call checks the reduction status. If the last blocker has cleared, the call completes the reduction and applies the requested minimum. It also resets Pool_Reduction to No_Reduction. Tasks that migrated during the reduction stay in their destination group.

Drain the automatic pool to a smaller size

Request_Pool_Reduction immediately lowers the ceiling for new automatic placements. The scheduler then moves eligible tasks from removed groups to group 0 at cooperative dispatch points.

If migration is necessary, the request can start group 0 and wait for its startup. A request that needs no migration starts no group. The call does not wait for the complete reduction. Query Pool_Reduction for the phase and blocker counts.

request and observe cooperative drainage
Result := Flyology.Execution_Groups.Request_Pool_Reduction (2);
Status := Flyology.Execution_Groups.Pool_Reduction;

if Status.Phase = Flyology.Execution_Groups.Draining then
   --  Poll again under an application-defined deadline.
   null;
end if;
FLYOLOGY_LOOP_POOL_SIZE
Selects 1 .. 128 shared groups for automatic round-robin placement at application startup. Groups and their OS threads still start lazily.
Grow_Configured_Pool
Raises that minimum later without moving existing tasks or starting unused groups.
Request_Pool_Reduction
Lowers the automatic-placement ceiling immediately and drains eligible automatically managed tasks cooperatively.

Migrate only at an explicit safe point

A lightweight task can call Flyology.Execution_Groups.Migrate to move to another Group_Id without changing its Ada task identity, stack, locals, or exception state. Current returns the calling lightweight task's group, and For_CPU converts a valid Ada CPU selector. Use a scoped thread pin while the task holds thread-affine foreign state. Use a dedicated group when the task also requires exclusive OS-thread ownership.

explicit migration
declare
   package Groups renames Flyology.Execution_Groups;
   Home : constant Groups.Group_Id := Groups.Current;
begin
   Groups.Migrate (Groups.For_CPU (2));
   Handle_Group_Owned_State;
   Groups.Migrate (Home);
end;