!standard D.10.1 (00) 09-10-23 AI05-0174-1/01 !class Amendment 09-10-23 !status work item 09-10-23 !status received 09-10-23 !priority High !difficulty Medium !subject Implement Task barriers in Ada !summary Add a Simple_Barrier type to allow many tasks to be blocked and be released at once. !problem As general purpose computing is moving to parallel architectures and eventually to massively parallel machines, there is a need to effeciently schedule many (hundreds or thousands) of tasks using barrier primitives. The POSIX OS and a number of machines provide a barrier where N tasks wait on a barrier and are released simultaneously when all N are ready to execute. Functionality like this should be added to Ada. !proposal There are many situations where the release of N tasks is required to execute an algorithm in parallel. Often the calculation is relatively small for each task on each iteration, but the number of tasks is high and the cost of linearly scheduling them and releasing them would remove almost any gains made through parallelizing them in the first place. The simple barrier release paradigm is that N-1 tasks are blocked on a common place waiting for release. One task is executing the sequential code prior to the parallel release. When that task suspends, the release condition is satisfied and all callers can execute. One of the callers is designated as the special task, which can perform sequential actions as the other tasks queue again for their next activity. We implement this functionality as an Ada package, a child of Ada.Synchronous_Task_Control: package Ada.Synchronous_Task_Control.Barriers is type Simple_Barrier(Number_Waiting : Positive) is limited private; procedure Wait_For_Release (The_Barrier : in out Simple_Barrier; Last_Released : out Boolean); end Ada.Synchronous_Task_Control.Barriers; When a variable of type Simple_Barrier is created with Number_Waiting = N, there are no waiting tasks and the barrier is set to block tasks. When the count reaches N, all tasks are simultaneously released and the "Last_Released" out parameter is set in [an arbitrary] one of the callers. When the scope closing the barrier is closed, the Simple_Barrier finalization is completed after all tasks waiting on the barrier have been removed from the barrier [via abort, termination, asynchronous transfer of control] Since it is expected that this functionality will often be mapped to hardware with a maximum number of release gates in a barrier construct, the maximum number of tasks that can be released using simple_barriers is implementation dependent. A system parameter, Maximum_Parallel_Release, provides this limit. !discussion This paradigm was discussed at IRTAW 14, Portovenere, Italy, 7-9 October 2009. We examined alternative syntax and semantics, such as - default setting of the barrier to True or to False, - explicit releasing of the tasks via Set_True as is done in suspension objects. We agreed that alternative functionality is needed to permit more complex interactions, but these require sharing some state and this is best done in the context of a highly optimized protected object. The extremely simple syntax and semantics provided for Simple_Barriers exactly matches the most common paradigm of N threads executing a single loop iteration and being released in a "for" loop from the loop evaluation release point. One of the threads will execute sequential parts of the program after the parallel portion is complete, but will execute its parallel portion prior to the sequential execution. The task that executes this part is determined by the return of a Boolean TRUE at the release of the barrier. It is implementation dependant whether or not the same task executes the sequential portion on different executions of a release from a single barrier. For the case of the protected object, we agreed on the following: New syntax is required. Protected object semantics must be preserved and be identical for the cases of completely parallel readers and sequential readers (i.e. on a single CPU). Blocking tasks must be able to be released once the count of blocked tasks on a single entry has been reached. Blocking tasks must be able to be released based on any arbitrary set of conditions. Where there is a single "final" task in the set of released tasks, it must block at a blockage point (such as a "then" in a "select ... then ... end select" until the reader count becomes 0 (or 1 if we started at N), then that final task executes the portion that writes to the protected state, including setting the lock for the entry subprogram barrier condition. In a sequential version of the program, the final task performs this action and does not need to wait. !example ** TBD ** --!corrigendum D.10.1(0) !ACATS test Add an ACATS C-Test to test the new package. !appendix ****************************************************************