CVS difference for ai12s/ai12-0119-1.txt

Differences between 1.11 and version 1.12
Log of other versions for file ai12s/ai12-0119-1.txt

--- ai12s/ai12-0119-1.txt	2018/01/10 00:58:39	1.11
+++ ai12s/ai12-0119-1.txt	2018/01/11 02:26:11	1.12
@@ -1,4 +1,4 @@
-!standard 5.5.2 (2/3)                              17-12-27    AI12-0119-1/05
+!standard 5.5.2 (2/3)                              18-01-01    AI12-0119-1/06
 !class Amendment 14-06-20
 !status work item 14-06-20
 !status received 14-06-17
@@ -27,15 +27,16 @@
 
 !proposal
 
+
 This proposal depends on the facilities for aspect Global (AI12-0079-1) and for
 aspect Nonblocking (AI12-0064-2). Those proposals allow the compiler to
 statically determine where parallelism may be introduced without introducing
-data races.
+data races or deadlocking.
 
 This proposal informally introduces the semantic notion of a Parallel
 OPportunity (POP) and a tasklet to the language. POPs are places in program text
 where work can be distributed to parallel executing workers that work in concert
-to correctly execute the algorithm. Tasklets are the notational (logical) units
+to correctly execute the algorithm. Tasklets are the notional (logical) units
 within a task that are executed in parallel with each other.
 
 The goals of this proposal are:
@@ -45,8 +46,8 @@
 - To support the development of complete programs that maximize
   parallelism;
 - To efficiently guide the compiler in the creation of effective
-  parallelism (without oversubscription) with minimal input from the
-  programmer;
+  parallelism (without oversubscription of the parallelism resources) with 
+  minimal input from the programmer;
 - To avoid syntax that would make a POP erroneous or produce noticeably
   different results if executed sequentially vs in parallel.
 
@@ -57,13 +58,17 @@
 
 Note that in this model the compiler will identify any code where a
 potential data race occurs (following the rules for concurrent access
-to objects as specified in the Language Reference Manual RM 9.10([23]{11???})),
+to objects as specified in the Language Reference Manual RM 9.10(11),
 and point out where objects cannot be guaranteed to be independently
 addressable. If not determinable at compile-time, the compiler may
 insert run-time checks to detect data overlap.
 
+This model also disallows potentially blocking operations within parallel
+block statements and parallel loop statements, to simplify the implementation
+of tasklets, and to eliminate possibilities of deadlocking from occurring.
+
 Another issue is the underlying runtime. In this model, tasklets are
-orthogonal to tasks. Regardless of implementation, tasklets are
+associated with tasks. Regardless of implementation, tasklets are
 considered to execute in the semantic context of the task where they
 have been spawned, which means that any operation that identifies a
 task, such as those in Task_Identification, will identify the task in
@@ -100,23 +105,24 @@
 parallel block are not automatically sequential, so execution can be
 erroneous if one such action assigns to an object, and the other reads
 or updates the same object or a neighboring object that is not
-independently addressable from the first object.  The appropriate use of
-atomic, protected, or task objects (which as a group we will call
-synchronized objects) can be used to avoid erroneous execution.
-
-In addition, the new Global and Potentially_Blocking aspects may be
-specified to enable the static detection of such problems at compile
-time (see AI12-0079-1 and AI12-0064-1).
+independently addressable from the first object.  Potentially blocking
+operations are not allowed in a parallel sequence of a parallel block.  
+Otherwise, the appropriate use of atomic, protected, or task objects (which as 
+a group we will call synchronized objects) can be used to avoid erroneous execution.
+
+In addition, the new Global and Nonblocking aspects may be specified to enable 
+the static detection of such problems at compile time (see AI12-0079-1 and 
+AI12-0064-1).
 
 Any transfer of control out of one parallel sequence will initiate the
 aborting of the other parallel sequences not yet completed.  Once all
 other parallel sequences complete normally or abort, the transfer of
 control takes place.  If multiple parallel sequences attempt a transfer
-of control before completing, the first occurrence of transfer of contgrol is
-chosen arbitrarily and the others are aborted.
+of control before completing, the first occurrence of transfer of control is 
+selected and the others are aborted.
 
 If an exception is raised by any of the parallel sequences, it is
-treated similarly to a transfer of control, with the exception being
+treated similarly to other forms of transfer of control, with the exception being
 propagated only after all the other sequences complete normally or due
 to abortion.  If multiple parallel sequences executing in parallel
 raise an exception before completing, the first occurrence is chosen and the
@@ -164,53 +170,33 @@
 {Legality Rules}
 A loop_statement shall not have both reserve words reverse and parallel present.
 
-A loop_statement with the parallel reserve word shall not update variables global
-to the loop unless either the action is sequential (see 9.10(11)), or the
+A loop_statement with the *parallel* reserve word shall not update variables global
+to the loop unless either the action is sequential (see 9.10(11)), or the 
 expression for the update mentions the loop parameter.
 
-New paragraph after 5.5 (9/4)
-
-For a parallel loop, a check is made that updates to a component of an global
-array or to an element of a container via an expression that mentions the loop
-parameter are sequential. See 9.10(11).
+The sequence_of_statements of a loop_statement with the *parallel* reserve word
+shall not consist of a statement that can invoke a potentially blocking operation (see 9.5(25)).
 
-AARM Reason:
-The check ensures that different tasklets executing iterations of the same loop
-in parallel will not involve data races. These checks are not needed if it can
-statically be determined that each iteration of the loop accesses a unique set
-of array components or container elements via the loop parameter.
-
-Add New paragraph after 5.5 (7)
-
-When the reserved word parallel is present and a transfer of control out of the
-loop occurs, an attempt is made to cancel further parallel execution of the
-sequence_of_statements that has not yet started. The completion of a
-loop_statement for a transfer of control out of the loop is delayed until all
-parallel execution of the sequence_of_statements is complete. If a transfer of
-control out of the loop occurs in multiple parallel executions of the
-sequence_of_statements then only the run time action of the first encountered
-transfer of control occurs.
-
 Modify to 5.5(9/4)
 
 "For the execution of a loop_statement with the iteration_scheme being for
  loop_parameter_specification, the loop_parameter_specification is first
- elaborated. This elaboration creates {objects of} the loop parameter and
+ elaborated. This elaboration creates {objects of} the loop parameter and 
  elaborates the discrete_subtype_definition. {If the keyword parallel is present,
- multiple objects of the loop parameter are created where each iteration is
+ multiple objects of the loop parameter are created where each iteration is 
  associated with a specific loop parameter object, otherwise a single loop
- parameter object is created. Each loop parameter object is associated with a
- thread of control where each thread proceeds independently and concurrently
- between the points where they interact with other tasks and with each other.}
- If the discrete_subtype_definition defines a subtype with a null range, the
- execution of the loop_statement is complete. Otherwise, the sequence_of_statements
- is executed once for each value of the discrete subtype defined by the
- discrete_subtype_definition that satisfies the predicates of the subtype (or
+ parameter object is created. Each loop parameter object is associated with a 
+ thread of control where each thread proceeds independently and concurrently 
+ between the points where they interact with other tasks and with each other.} 
+ If the discrete_subtype_definition defines a subtype with a null range, the 
+ execution of the loop_statement is complete. Otherwise, the sequence_of_statements 
+ is executed once for each value of the discrete subtype defined by the 
+ discrete_subtype_definition that satisfies the predicates of the subtype (or 
  until the loop is left as a consequence of a transfer of control).
  Prior to each such iteration, the corresponding value of the discrete subtype
- is assigned to [the]{a} loop parameter {object}. These values are assigned in
- increasing order unless the reserved word reverse is present, in which case the
- values are assigned in decreasing order {or unless the reserved word parallel
+ is assigned to [the]{a} loop parameter {object}. These values are assigned in 
+ increasing order unless the reserved word reverse is present, in which case the 
+ values are assigned in decreasing order {, or unless the reserved word parallel 
  is present, in which case the order is arbitrary}. "
 
 AARM - An implementation should statically treat the
@@ -218,9 +204,32 @@
 but whether they actually execute in parallel or sequentially should be a
 determination that is made dynamically at run time, dependent on factors
 such as the available computing resources.
+
+New paragraph after 5.5 (9/4)
 
-Examples after 5.5(20)
+For a parallel loop, a check is made that updates to a component of a global
+array or to an element of a container via an expression that mentions the loop
+parameter sequential. See 9.10(11).
+
+AARM Reason:
+The check ensures that different tasklets executing iterations of the same loop
+in parallel will not involve data races. These checks are not needed if it can
+statically be determined that each iteration of the loop accesses a unique set
+of array components or container elements via the loop parameter.
 
+Add New paragraph after 5.5 (7)
+
+When the reserved word parallel is present and a transfer of control out of the
+loop occurs, an attempt is made to cancel further parallel execution of the
+sequence_of_statements that has not yet started. The completion of a 
+loop_statement for a transfer of control out of the loop is delayed until all 
+parallel execution of the sequence_of_statements is complete. If a transfer of 
+control out of the loop occurs in multiple parallel executions of the 
+sequence_of_statements then only the run time action of the first encountered 
+transfer of control occurs.
+
+Examples after 5.5(21)
+
 Example of a parallel loop
 
 -- See 3.6(30/2)
@@ -234,215 +243,251 @@
 with Ada.Containers;
 
 Add after 5.5.1 (4/3)
-
-   use type Ada.Containers.Count_Type;
-   subtype Count_Type is Ada.Containers.Count_Type;
 
-   type Cursor_Offset is range -(Count_Type'Last - 1) .. Count_Type'Last - 1;
+   type Chunk_Array is limited interface
+     with Nonblocking;
 
-   type Parallel_Iterator is limited interface and Forward_Iterator;
-
    function Length
-     (Object   : Parallel_Iterator) return Count_Type is abstract;
-
-   function Jump
-     (Object   : Parallel_Iterator;
-      Position : Cursor;
-      Offset   : Cursor_Offset) return Cursor is abstract;
+     (Object  : Chunk_Array) return Natural is abstract;
 
-   type Reversible_Parallel_Iterator is
-      limited interface and Parallel_Iterator and Reversible_Iterator;
-
+   function Start
+     (Object : Chunk_Array;
+      Index  : Natural) return Cursor is abstract;
+
+   function Finish
+     (Object : Chunk_Array;
+      Index  : Natural) return Cursor is abstract;
+
+   type Parallel_Iterator is limited interface and Forward_Iterator
+      with Nonblocking;
+
+   function Iterations
+     (Object : Parallel_Iterator)
+      return Ada.Containers.Count_Type is abstract;
+
+   function Split
+     (Object        : Parallel_Iterator;
+      Advised_Split : Natural)
+      return Chunk_Array'Class is abstract;
+
+   type Parallel_Reversible_Iterator is limited interface
+     and Parallel_Iterator and Reversible_Iterator
+       with Nonblocking;
+      
 Modify 5.5.1 (6/3)
 
-An iterator type is a type descended from the Forward_Iterator
-interface from some instance of Ada.Iterator_Interfaces. A reversible iterator
-type is a type descended from the Reversible_Iterator interface from some
-instance of Ada.Iterator_Interfaces. {A parallel iterator type is a type
-descended from the Parallel_Iterator interface from some instance of
+An iterator type is a type descended from the Forward_Iterator 
+interface from some instance of Ada.Iterator_Interfaces. A reversible iterator 
+type is a type descended from the Reversible_Iterator interface from some 
+instance of Ada.Iterator_Interfaces. {A parallel iterator type is a type 
+descended from the Parallel_Iterator interface from some instance of 
 Ada.Iterator_Interfaces. A parallel reversible iterator type is a type
-decended from both the Parallel_Iterator interace and the Reversible_Iterator
+descended from both the Parallel_Iterator interace and the Reversible_Iterator
 interface from some instance of Ada.Iterator_Interfaces.} An iterator object is
-an object of an iterator type. A reversible iterator object is an object of a
-reversible iterator type{, a parallel iterator object is an object of a parallel
-iterator type, and a parallel reversible iterator object is an object of a
-parallel reversible iterator type.} The formal subtype Cursor from the associated
+an object of an iterator type. A reversible iterator object is an object of a 
+reversible iterator type. { A parallel iterator object is an object of a parallel 
+iterator type. A parallel reversible iterator object is an object of a 
+parallel reversible iterator type.} The formal subtype Cursor from the associated 
 instance of Ada.Iterator_Interfaces is the iteration cursor subtype for the iterator type.
-
+      
 Modify 5.5.1 (11/3)
 
-An iterable container type is an indexable container type with specified
-Default_Iterator and Iterator_Element aspects. A reversible iterable container
-type is an iterable container type with the default iterator type being a
-reversible iterator type. {A parallel iterable container type is an iterable
+An iterable container type is an indexable container type with specified 
+Default_Iterator and Iterator_Element aspects. A reversible iterable container 
+type is an iterable container type with the default iterator type being a 
+reversible iterator type. {A parallel iterable container type is an iterable 
 container type with the default iterator type being a parallel iterator type. A
 parallel reversible iterable container type is an iterable container type with the
-default iterator type being a parallel reversible iterator type.}
-An iterable container object is an object of an iterable container type. A
-reversible iterable container object is an object of a reversible iterable
-container type. {A parallel iterable container object is an object of a parallel
+default iterator type being a parallel reversible iterator type.} 
+An iterable container object is an object of an iterable container type. A 
+reversible iterable container object is an object of a reversible iterable 
+container type. {A parallel iterable container object is an object of a parallel 
 iterable container type. A parallel reversible iterable container object is an
 object of a parallel reversible iterable container type.}
 
 Modify 5.5.2 (4/3)
 
-If the reserved word reverse appears, the iterator_specification is a reverse
-iterator[.;] {If the reserved word parallel appears, the iterator_specificaiton
-is a parallel iterator;} otherwise it is a forward iterator. In a reverse
-generalized iterator, the iterator_name shall be of a reversible iterator type.
-{In a parallel generalized iterator, the iterator_name shall be of a parallel
-iterator type.} In a reverse container element iterator, the default
-iterator type for the type of the iterable_name shall be a reversible iterator
-type. {In a parallel container element iterator, the default iterator type for
+If the reserved word reverse appears, the iterator_specification is a reverse 
+iterator[.;] {If the reserved word parallel appears, the iterator_specification 
+is a parallel iterator;} otherwise it is a forward iterator. In a reverse 
+generalized iterator, the iterator_name shall be of a reversible iterator type. 
+{In a parallel generalized iterator, the iterator_name shall be of a parallel 
+iterator type.} In a reverse container element iterator, the default 
+iterator type for the type of the iterable_name shall be a reversible iterator 
+type. {In a parallel container element iterator, the default iterator type for 
 the type of the iterable_name shall be of a parallel iterator type.}
 
 Modify 5.5.2 (7/5)
 
-An iterator_specification declares a {set of} loop parameter {objects. If the
- keyword parallel is present, multiple objects of the loop parameter are
- created where each iteration is associated with a specific loop parameter
- object; otherwise a single loop parameter object is created for the loop. Each
- loop parameter object is associated with a thread of control where each thread
- of control proceeds independently and concurrently between the points
- where they interact with other tasks and with each other}. In a generalized
- iterator, an array component iterator, or a container element iterator,
- if a loop_parameter_subtype_indication is present, it determines the nominal
- subtype of the loop parameter{s}. In a generalized iterator, if a
- loop_parameter_subtype_indication is not present, the nominal subtype of the
- loop parameter{s are} [is] the iteration cursor subtype. In an array component
- iterator, if a loop_parameter_subtype_indication is not present, the nominal
- subtype of the loop parameter{s are}[ is] the component subtype of the type of
- the iterable_name. In a container element iterator, if a
- loop_parameter_subtype_indication is not present, the nominal subtype of the
+An iterator_specification declares a {set of} loop parameter {objects. If the 
+ keyword parallel is present, multiple objects of the loop parameter are 
+ created where each iteration is associated with a specific loop parameter 
+ object; otherwise a single loop parameter object is created for the loop. Each 
+ loop parameter object is associated with a thread of control where each thread 
+ of control proceeds independently and concurrently between the points 
+ where they interact with other tasks and with each other}. In a generalized 
+ iterator, an array component iterator, or a container element iterator, 
+ if a loop_parameter_subtype_indication is present, it determines the nominal 
+ subtype of the loop parameter{s}. In a generalized iterator, if a 
+ loop_parameter_subtype_indication is not present, the nominal subtype of the 
+ loop parameter{s} is the iteration cursor subtype. In an array component 
+ iterator, if a loop_parameter_subtype_indication is not present, the nominal 
+ subtype of the loop parameter{s are}[ is] the component subtype of the type of 
+ the iterable_name. In a container element iterator, if a 
+ loop_parameter_subtype_indication is not present, the nominal subtype of the 
  loop parameter{s are}[is] the default element subtype for the type of the iterable_name.
 
 Modify 5.5.2 (8/3)
-In a generalized iterator, the loop parameter{s are} [is a] constant. In an
-array component iterator, the loop parameter{s are} [is a] constant if the
-iterable_name denotes a constant; otherwise it denotes a variable. In a container
-element iterator, the loop parameter{s are}[is a] constant if the iterable_name
-denotes a constant, or if the Variable_Indexing aspect is not specified for the
-type of the iterable_name; otherwise it is a variable.
+In a generalized iterator, the loop parameter{s are} [is a] constant. In an 
+array component iterator, the loop parameter{s are} [is a] constant if the 
+iterable_name denotes a constant; otherwise [it]{they} denote[s] a variable. 
+In a container element iterator, the loop parameter{s are}[is a] constant if the 
+iterable_name denotes a constant, or if the Variable_Indexing aspect is not 
+specified for the type of the iterable_name; otherwise it is a variable.
 
 Modify 5.5.2 (8.a/5)
 
-Ramification: The loop parameter{s} of a generalized iterator {have}[has] the
-same accessibility as the loop statement. This means that the loop parameter
-object{s} {are}[is] finalized when the loop statement is left. ([It]{They} also
-may be finalized as part of assigning a new value to the loop parameter{s}.) For array
-component iterators, the loop parameter{s each} directly denotes an element of
-the array and [has]{have} the accessibility of the associated array. For container
-element iterators, the loop parameter{s each} denotes the result of [the]{an}
-indexing function call (in the case of a constant indexing) or a generalized
-reference thereof (in the case of a variable indexing). Roughly speaking, the
-loop parameter{s have} [has] the accessibility level of a single iteration of
-the loop. More precisely, the function result (or the generalized reference
-thereof) is considered to be renamed in the declarative part of a notional block
-statement which immediately encloses the loop's sequence_of_statements; the
+Ramification: The loop parameter{s} of a generalized iterator {have}[has] the 
+same accessibility as the loop statement. This means that the loop parameter 
+object{s} {are}[is] finalized when the loop statement is left. ([It]{They} also 
+may be finalized as part of assigning a new value to the loop parameter{s}.) For array 
+component iterators, the loop parameter{s each} directly denotes an element of 
+the array and [has]{have} the accessibility of the associated array. For container 
+element iterators, the loop parameter{s each} denotes the result of [the]{an} 
+indexing function call (in the case of a constant indexing) or a generalized 
+reference thereof (in the case of a variable indexing). Roughly speaking, the 
+loop parameter{s have} [has] the accessibility level of a single iteration of 
+the loop. More precisely, the function result (or the generalized reference 
+thereof) is considered to be renamed in the declarative part of a notional block 
+statement which immediately encloses the loop's sequence_of_statements; the 
 accessibility of the loop parameter{s are} [is] that of the block statement.
 
 Modify 5.5.2 (10/3)
 
-For a generalized iterator, the loop parameter{s are} [is] created, the
-iterator_name is evaluated, and the denoted iterator object{s} becomes the loop
-iterator{s}. In a forward generalized iterator, the operation First of the
-iterator type is called on the loop iterator, to produce the initial value for
-the loop parameter. If the result of calling Has_Element on the initial value is
-False, then the execution of the loop_statement is complete. Otherwise, the
-sequence_of_statements is executed and then the Next operation of the iterator
-type is called with the loop iterator and the current value of the loop
-parameter to produce the next value to be assigned to the loop parameter. This
-repeats until the result of calling Has_Element on the loop parameter is False,
-or the loop is left as a consequence of a transfer of control. For a
-reverse generalized iterator, the operations Last and Previous are called rather
-than First and Next. {For a parallel generalized iterator, the operation Length
-of the iterator type is called first to determine the number of iterations that
-can execute in parallel. If the result of calling Length is 0, then the execution
-of the loop_statement is complete. Otherwise, the operation First of
-the iterator type is then called on a loop iterator, to produce the initial
-value for one of the associated loop parameters. The operation Jump of the
-iterator type is then called using the result of the First call as an input, and
-then repeatedly using the result from each previous call to produce the inital
-value of the remaining associated loop parameters. The threads of control
-associated with each loop parameter execute until all threads have completed
-execution of their associated iterations, or the loop is left as a consequence
-of a transfer of control.}
+For a generalized iterator, the loop parameter{s are} [is] created, the 
+iterator_name is evaluated, and the denoted iterator object{s} become[s] the loop 
+iterator{s}. In a forward generalized iterator, the operation First of the 
+iterator type is called on the loop iterator, to produce the initial value for 
+the loop parameter. If the result of calling Has_Element on the initial value is 
+False, then the execution of the loop_statement is complete. Otherwise, the 
+sequence_of_statements is executed and then the Next operation of the iterator 
+type is called with the loop iterator and the current value of the loop 
+parameter to produce the next value to be assigned to the loop parameter. This 
+repeats until the result of calling Has_Element on the loop parameter is False, 
+or the loop is left as a consequence of a transfer of control. For a 
+reverse generalized iterator, the operations Last and Previous are called rather 
+than First and Next. 
+
+{For a parallel generalized iterator, the operation Iterations
+of the iterator type is called first to determine the number of iterations associated
+with the iterator. If the result of calling Iterations is 0, then the execution
+of the loop_statement is complete. Otherwise, the operation Split of
+the iterator type is then called on a loop iterator, with the Advised_Split parameter
+value set to a value determined by the implementation that indicates a recommendation
+for the number of loop parameter objects that should be created. The result of the
+call to Split is a Chunk_Array object that indicates the number of loop parameter
+objects to be created by the implementation, as well as the range of cursor values 
+to be uniquely associated with each loop parameter object. The number of loop parameters
+to be created is determined by calling Length operation of the Chunk_Array.
+The range of cursor values to be associated with each loop parameter is determined
+by calling the Start and Finish operation of the Chunk_Array object using an
+ordinal index value of the loop parameter object as the Index parameter for these calls.
+The result of calling the Start operation is the initial cursor value to be assigned
+to a given loop parameter object. The result of calling the Finish operation is the final
+cursor value to be iterated for a given loop parameter object. The 
+sequence_of_statements is executed for each loop parameter object and then the Next 
+operation of the iterator type is called with the loop iterator and the current value of the loop 
+parameter to produce the next value to be assigned to a given loop parameter. This 
+repeats until the value of the loop parameter is equal to the final cursor value associated
+with the given loop parameter, or the loop is left as a consequence of a transfer of control.}
 
 AARM Note
 
-Jump is used rather than Next, to provide better support for implementations
-to apply loop chunking, where each thread of control might be responsible for multiple
-loop iterations. For instances, it is more efficient for a Vector to call Jump to determine
-the cursor for the next chunk, via a single call, rather than issue multiple calls to
-Next to arrive at the same cursor position.
+The Advised_Split parameter value is only a recommendation by the implementation.
+A container implementation may choose to ignore that recommendation if a more
+optimal split can be determined. For instance, a tree based container might create
+the split based on the number of branches at the top levels of the tree.
 
 Modify 5.5.2 (10.a/4)
 
-Ramification: The loop parameter{s} of a generalized iterator [is a]{are} variable{s}
-of which the user only has a constant view. It follows the normal rules for a
-variable of its nominal subtype. In particular, if the nominal subtype is indefinite,
-the variable is constrained by its initial value. Similarly, if the nominal subtype
-is class-wide, the variable (like all variables) has the tag of the initial value.
-Constraint_Error may be raised by a subsequent iteration if Next{, }[ or] Previous{, or Jump}
-return an object with a different tag or constraint.
+Ramification: The loop parameter{s} of a generalized iterator [is a]{are} variable{s} 
+of which the user only has a constant view. It follows the normal rules for a 
+variable of its nominal subtype. In particular, if the nominal subtype is indefinite, 
+the variable is constrained by its initial value. Similarly, if the nominal subtype 
+is class-wide, the variable (like all variables) has the tag of the initial value. 
+Constraint_Error may be raised by a subsequent iteration if Next{, }[ or] Previous{, or Split} 
+return an object with a different tag or constraint. 
 
 Modify 5.5.2 (11/3)
 
-For an array component iterator, the iterable_name is evaluated and the denoted
-array object becomes the array for the loop. If the array for the loop is a
-null array, then the execution of the loop_statement is complete. Otherwise, {if
-the iterator is not a parallel array component iterator,} the sequence_of_statements
-is executed with the loop parameter denoting each component of the array for the loop,
-using a canonical order of components, which is last dimension varying fastest
-(unless the array has convention Fortran, in which case it is first dimension
-varying fastest). For a forward array component iterator, the iteration starts
-with the component whose index values are each the first in their index range,
-and continues in the canonical order. For a reverse array component iterator, the
-iteration starts with the component whose index values are each the last in their
-index range, and continues in the reverse of the canonical order. {For a parallel
-array component iterator, the order of iteration is arbitrary.} The loop iteration
-proceeds until the sequence_of_statements has been executed for each component of
-the array for the loop, or until the loop is left as a consequence of a transfer of
+For an array component iterator, the iterable_name is evaluated and the denoted 
+array object becomes the array for the loop. If the array for the loop is a 
+null array, then the execution of the loop_statement is complete. Otherwise,
+the sequence_of_statements is executed with [the] loop parameter{s that collectively 
+denote} [denoting] each component of the array for the loop{. If 
+the iterator is not a parallel array component iterator, the loop is iterated} 
+using a canonical order of components, which is last dimension varying fastest 
+(unless the array has convention Fortran, in which case it is first dimension 
+varying fastest). For a forward array component iterator, the iteration starts 
+with the component whose index values are each the first in their index range, 
+and continues in the canonical order. For a reverse array component iterator, the 
+iteration starts with the component whose index values are each the last in their 
+index range, and continues in the reverse of the canonical order. {For a parallel 
+array component iterator, the order of iteration is arbitrary.} The loop iteration 
+proceeds until the sequence_of_statements has been executed for each component of 
+the array for the loop, or until the loop is left as a consequence of a transfer of 
 control.
 
 Modify 5.5.2 (12/3)
 
-For a container element iterator, the iterable_name is evaluated and the denoted
-iterable container object becomes the iterable container object for the loop.
-The default iterator function for the type of the iterable container object for
-the loop is called on the iterable container object and the result is the loop
-iterator. [An object] {Objects} of the default cursor subtype [is]{are} created
+For a container element iterator, the iterable_name is evaluated and the denoted 
+iterable container object becomes the iterable container object for the loop. 
+The default iterator function for the type of the iterable container object for 
+the loop is called on the iterable container object and the result is the loop 
+iterator. [An object] {Objects} of the default cursor subtype [is]{are} created 
 (the loop cursor{s}).
 
 Modify 5.5.2 (13/3)
 
-For a forward container element iterator, the operation First of the iterator
-type is called on the loop iterator, to produce the initial value for the loop
-cursor. If the result of calling Has_Element on the initial value is False, then
-the execution of the loop_statement is complete. Otherwise, the sequence_of_statements
-is executed with the loop parameter denoting an indexing (see 4.1.6) into the
-iterable container object for the loop, with the only parameter to the indexing
-being the current value of the loop cursor; then the Next operation of the iterator
-type is called with the loop iterator and the loop cursor to produce the next value
-to be assigned to the loop cursor. This repeats until the result of calling
-Has_Element on the loop cursor is False, or until the loop is left as a consequence
-of a transfer of control. For a reverse container element iterator, the operations
-Last and Previous are called rather than First and Next. {For a parallel container
-element iterator, the operation Length is first called to determine the number of
-iterations that can execute in parallel. If the result of calling Length is 0,
-then the execution of the loop_statement is complete. Otherwise, the operation
-First of the iterator type is then called on a loop iterator, to produce the initial
-value for one of the associated loop parameters. The operation Jump of the
-iterator type is then called with the loop iterator and the result of First, to produce
-the initial value for the next loop cursor. Repeated calls to Jump using the loop
-iterator and the previous loop cursor result from the Jump call are used to produce
-the initial value of the remaining loop cursors. The threads of control
-associated with each loop cursor execute until all threads have completed
-execution of their associated iterations, or the loop is left as a consequence
-of a transfer of control.} If the loop parameter is a constant (see above), then
-the indexing uses the default constant indexing function for the type of the
-iterable container object for the loop; otherwise it uses the default variable
-indexing function.
+For a forward container element iterator, the operation First of the iterator 
+type is called on the loop iterator, to produce the initial value for the loop 
+cursor. If the result of calling Has_Element on the initial value is False, then 
+the execution of the loop_statement is complete. Otherwise, the sequence_of_statements 
+is executed with the loop parameter denoting an indexing (see 4.1.6) into the 
+iterable container object for the loop, with the only parameter to the indexing 
+being the current value of the loop cursor; then the Next operation of the iterator 
+type is called with the loop iterator and the loop cursor to produce the next value 
+to be assigned to the loop cursor. This repeats until the result of calling 
+Has_Element on the loop cursor is False, or until the loop is left as a consequence 
+of a transfer of control. For a reverse container element iterator, the operations 
+Last and Previous are called rather than First and Next. 
+
+{For a parallel container element iterator, the operation Iterations is first called 
+to determine the number of iterations associated with the iterator. If the result of 
+calling Iterations is 0, then the execution of the loop_statement is complete. Otherwise,
+the operation Split of the iterator type is then called on a loop iterator, with the 
+Advised_Split parameter value set to a value determined by the implementation that 
+indicates a recommendation for the number of loop parameter objects that should be 
+created. The result of the call to Split is a Chunk_Array object that indicates 
+the number of loop parameter objects to be created by the implementation, as well 
+as the range of cursor values to be uniquely associated with each loop parameter 
+object. The number of loop parameters to be created is determined by calling the Length 
+operation of the Chunk_Array. The range of cursor values to be associated with each 
+loop parameter is determined by calling the Start and Finish operation of the 
+Chunk_Array object using an ordinal index value of the loop parameter object as 
+the Index parameter for these calls. The result of calling the Start operation is 
+the initial cursor value to be assigned to a given loop parameter object. The result 
+of calling the Finish operation is the final cursor value to be iterated for a given 
+loop parameter object. The sequence_of_statements is executed for each loop parameter 
+object and then the Next operation of the iterator type is called with the loop iterator 
+and the current value of the loop parameter to produce the next value to be assigned to a 
+given loop parameter. This repeats until the value of the loop parameter is equal to 
+the final cursor value associated with the given loop parameter, or the loop is left 
+as a consequence of a transfer of control.}
+
+If the loop parameter is a constant  (see above), then the indexing uses the 
+default constant indexing function for the type of the iterable container object 
+for the loop; otherwise it uses the default variable indexing function.
 
 Modify 5.5.2 (15/3)
 
@@ -452,12 +497,83 @@
    Element := Element * 2.0; -- Double each element of Board, a two-dimensional array.
 end loop;
 
+Add new Section 5.5.3
 
-"5.6.1 Parallel Block Statements
+User-Defined Parallel Loop Chunking for Discrete Types
 
-[A parallel_block_statement encloses two or more handled_sequence_of_statements
+The following language-defined generic library package exists: 
+
+with Ada.Iterator_Interfaces;
+with Ada.Containers;
+
+generic
+   type Loop_Index is (<>);
+package Ada.Discrete_Chunking is
+
+   pragma Preelaborate;
+   pragma Remote_Types;
+
+   function Has_Element (Position : Loop_Index) return Boolean is (True);
+
+   package Chunk_Array_Iterator_Interfaces is new
+     Ada.Iterator_Interfaces (Loop_Index, Has_Element);
+
+   function Split
+     (Chunks : Natural;
+      From   : Loop_Index := Loop_Index'First;
+      To     : Loop_Index := Loop_Index'Last)
+   return Chunk_Array_Iterator_Interfaces.Chunk_Array'Class
+     with Pre => Chunks <= Loop_Index'Pos(To) - Loop_Index'Pos(From) + 1,
+          Nonblocking => False;
+
+private
+   ... -- not specified by the language
+end Ada.Discrete_Chunking;
+
+   function Split
+     (Chunks : Positive;
+      From   : Loop_Index := Loop_Index'First;
+      To     : Loop_Index := Loop_Index'Last)
+   return Chunk_Array_Iterator_Interfaces.Chunk_Array'Class
+     with Pre => Chunks <= Loop_Index'Pos(To) - Loop_Index'Pos(From) + 1;
+
+Split returns a Chunk_Array object (see 5.5.1) for user-defined parallel 
+iteration over a range of values of a discrete subtype starting with the value
+From and ending with the value To. The Chunks value indicates the number of Executors
+(see 9.12) to be associated with the parallel loop, which equals the value returned
+by calling the Length operation on the Chunk_Array result. 
+
+Examples
+
+  declare     
+     package Manual_Chunking is new Ada.Discrete_Chunking (Integer);
+
+     Chunks : constant
+        Manual_Chunking.Chunk_Array_Iterator_Interfaces.Chunk_Array'Class :=
+          Manual_Chunking.Split (Chunks => 4);
+  begin
+     parallel
+     for Chunk in 1 .. Chunks.Length loop
+        declare
+           File : Text_IO.File_Type;
+        begin
+           Text_IO.Create(File => File,
+                          Name => Natural'Image(Chunk) & ".txt");
+
+           for I in Chunks.Start(Chunk) .. Chunks.Finish(Chunk) loop
+              Put_Line (Integer'Image(I) & "=" & Integer'Image (A(I));
+           end loop;
+           
+           Text_IO.Close(File);
+        end;
+     end loop;
+  end;
+
+5.6.1 Parallel Block Statements
+
+A parallel_block_statement encloses two or more handled_sequence_of_statements
 where all the handled_sequence_of_statements can execute in parallel with each
-other.]
+other.
 
 Syntax
 
@@ -470,12 +586,15 @@
    {and
       handled_sequence_of_statements}
     end do;
-
+    
 Legality Rules
 
 A parallel_block_statement shall not update variables global to the loop unless
 the action is sequential (see 9.10(11)).
 
+A handled_sequence_of_statements of a parallel_block_statement shall not consist 
+of a statement that can invoke a potentially blocking operation (see 9.5(25)).
+
 Static Semantics
 
 Each handled_sequence_of_statements represents a separate thread of control that
@@ -483,14 +602,14 @@
 interact with other tasks and with each other.
 
 For the execution of a parallel_block_statement, each handled_sequence_of_statements
-is executed once, until the parallel_block_statement is complete. The
+is executed once, until the parallel_block_statement is complete. The 
 parallel_block_statement is complete when all handled_sequence_of_statements have
-completed execution or when transfer of control occurs that transfers
-control out of the parallel block. When a transfer of control out of the
+completed execution or when transfer of control occurs that transfers 
+control out of the parallel block. When a transfer of control out of the 
 parallel block occurs, an attempt is made to cancel further parallel execution of
-a handled_sequence_of_statements that have not yet started. The completion of a
-parallel_block_statement for a transfer of control out
-of the parallel block is delayed until all parallel execution of the handled_sequence_of_statements
+a handled_sequence_of_statements that have not yet started. The completion of a 
+parallel_block_statement for a transfer of control out 
+of the parallel block is delayed until all parallel execution of the handled_sequence_of_statements 
 is complete. If a transfer of control out of the loop occurs in multiple parallel
 executions of handled_sequence_of_statements then only the run time action of the first
 encountered transfer of control out of the parallel block occurs.
@@ -518,12 +637,29 @@
           Put_Line ("Constraint Error raised doing Other_Work");
    end do;
 
+   function Fibonacci (N : Natural) return Natural is
+      X, Y : Natural;
+   begin
+      if N < 2 then
+         return N;
+      end if;
+
+      parallel
+      do
+        X := Fibonacci (N - 2);
+      and
+        Y := Fibonacci (N - 1);
+      end do;
+
+      return X + Y;
+   end Fibonacci;
+
 Change 9.10 (13)
 
 "Both actions occur as part of the execution of the same task {unless
  either are part of a;
    - different handled_sequence_of_statements of a parallel block statement,
-   - parallel loop statement.}"
+   - sequence_of_statements of a parallel loop statement.}"
 
 New section 9.12 Executors and Tasklets
 
@@ -537,14 +673,14 @@
 execution until all the executors have completed their respective
 executions.
 
-A parallel block statement or parallel loop statement may assign a set of
+A parallel block statement or parallel loop statement may assign a set of 
 executors to execute the construct, if extra computing resources are available.
 
 Add new paragraph after 11.5 (20)
 
 Loop_Parameter_Check
   For a parallel loop, check that updates to a component of an array or to an
-  elememnt of a container via the loop parameter are sequential. See 9.10(11).
+  element of a container via the loop parameter are sequential. See 9.10(11). 
 
 Modify A.18.2(74.1/3)
 
@@ -563,16 +699,16 @@
 
 Modify A.18.2 (230.2/3)
 
-Iterate returns a {parallel} reversible iterator object (see 5.5.1) that will
-generate a value for [a] loop parameter{s} (see 5.5.2) designating each node in
-Container, starting with the first node and moving the cursor as per the Next
-function when used as a forward iterator, and starting with the last node and
+Iterate returns a {parallel} reversible iterator object (see 5.5.1) that will 
+generate a value for [a] loop parameter{s} (see 5.5.2) designating each node in 
+Container, starting with the first node and moving the cursor as per the Next 
+function when used as a forward iterator, and starting with the last node and 
 moving the cursor as per the Previous function when used as a reverse iterator
-{, and starting with all notes simultaneously using the First and Jump functions
-to generate cursors for all the iterations of the loop when used as a parallel
-iterator}. Tampering with the cursors of Container is prohibited while the
-iterator object exists (in particular, in the sequence_of_statements of the
-loop_statement whose iterator_specification denotes this object). The iterator
+{, and starting with all nodes simultaneously using the Split function
+to generate cursors for all the iterations of the loop when used as a parallel 
+iterator}. Tampering with the cursors of Container is prohibited while the 
+iterator object exists (in particular, in the sequence_of_statements of the 
+loop_statement whose iterator_specification denotes this object). The iterator 
 object needs finalization.
 
 Modify A.18.2 (230.3/3)
@@ -582,17 +718,16 @@
 
 Modify A.18.2 (230.4/3)
 
-If Start is not No_Element and does not designate an item in Container, then
-Program_Error is propagated. If Start is No_Element, then Constraint_Error is
-propagated. Otherwise, Iterate returns a {parallel }reversible iterator object
-(see 5.5.1) that will generate a value for [a] loop parameter{s} (see 5.5.2)
-designating each node in Container, starting with the node designated by Start
-and moving the cursor as per the Next function when used as a forward iterator,
+If Start is not No_Element and does not designate an item in Container, then 
+Program_Error is propagated. If Start is No_Element, then Constraint_Error is 
+propagated. Otherwise, Iterate returns a {parallel }reversible iterator object 
+(see 5.5.1) that will generate a value for [a] loop parameter{s} (see 5.5.2) 
+designating each node in Container, starting with the node designated by Start 
+and moving the cursor as per the Next function when used as a forward iterator, 
 or moving the cursor as per the Previous function when used as a reverse iterator
-{, or all nodes simulataneously starting with the node designated by Start and obtaining
-the other cursors via calls to Jump when used as a parallel iterator}. Tampering
-with the cursors of Container is prohibited while the iterator object exists (in
-particular, in the sequence_of_statements of the loop_statement whose
+{, or all nodes simultaneously using the Split function when used as a parallel 
+iterator}. Tampering with the cursors of Container is prohibited while the iterator 
+object exists (in particular, in the sequence_of_statements of the loop_statement whose 
 iterator_specification denotes this object). The iterator object needs finalization.
 
 Modify A.18.3 (46.1/3)
@@ -612,15 +747,15 @@
 
 Modify A.18.3 (144.2/3)
 
-Iterate returns a {parallel }reversible iterator object (see 5.5.1) that will
-generate a value for [a] loop parameter{s} (see 5.5.2) designating each node in
-Container, starting with the first node and moving the cursor as per the Next
-function when used as a forward iterator, and starting with the last node and
+Iterate returns a {parallel }reversible iterator object (see 5.5.1) that will 
+generate a value for [a] loop parameter{s} (see 5.5.2) designating each node in 
+Container, starting with the first node and moving the cursor as per the Next 
+function when used as a forward iterator, and starting with the last node and 
 moving the cursor as per the Previous function when used as a reverse iterator
-{, and starting with all notes simultaneously using the First and Jump functions
+{, and starting with all nodes simultaneously using the Split function
 to generate cursors for all the iterations of the loop when used as a parallel
-iterator}. Tampering with the cursors of Container is prohibited while the iterator
-object exists (in particular, in the sequence_of_statements of the loop_statement
+iterator}. Tampering with the cursors of Container is prohibited while the iterator 
+object exists (in particular, in the sequence_of_statements of the loop_statement 
 whose iterator_specification denotes this object). The iterator object needs finalization.
 
 Modify A.18.3 (144.3/3)
@@ -630,17 +765,16 @@
 
 Modify A.18.3 (144.4/3)
 
-If Start is not No_Element and does not designate an item in Container, then
-Program_Error is propagated. If Start is No_Element, then Constraint_Error is
-propagated. Otherwise, Iterate returns a {parallel} reversible iterator object
-(see 5.5.1) that will generate [a] value{s} for [a] loop parameter{s} (see 5.5.2)
-designating each node in Container, starting with the node designated by Start
-and moving the cursor as per the Next function when used as a forward iterator,
+If Start is not No_Element and does not designate an item in Container, then 
+Program_Error is propagated. If Start is No_Element, then Constraint_Error is 
+propagated. Otherwise, Iterate returns a {parallel} reversible iterator object 
+(see 5.5.1) that will generate [a] value{s} for [a] loop parameter{s} (see 5.5.2) 
+designating each node in Container, starting with the node designated by Start 
+and moving the cursor as per the Next function when used as a forward iterator, 
 or moving the cursor as per the Previous function when used as a reverse iterator
-{or all nodes simulataneously starting with the node designated by Start and obtaining
-the other cursors via calls to Jump when used as a parallel iterator}. Tampering
-with the cursors of Container is prohibited while the iterator object exists (in
-particular, in the sequence_of_statements of the loop_statement whose
+{or all nodes simultaneously using the Split function when used as a parallel iterator}.
+Tampering with the cursors of Container is prohibited while the iterator object exists (in 
+particular, in the sequence_of_statements of the loop_statement whose 
 iterator_specification denotes this object). The iterator object needs finalization.
 
 Modify A.18.5 (37.1/3)
@@ -654,14 +788,14 @@
    return Map_Iterator_Interfaces.{Parallel}[Forward]_Iterator'Class;
 
 Modify A.18.5 (61.2/3)
-Iterate returns a[n] {parallel} iterator object (see 5.5.1) that will generate [a]
-value{s} for [a] loop parameter{s} (see 5.5.2) designating each node in Container, starting
-with the first node and moving the cursor according to the successor relation
-{when used as a forward iterator, and starting with all nodes simultaneously using
-the First and Jump functions to generate cursors for all the iterations of the loop
-when used as a parallel iterator}. Tampering with the cursors of Container is
-prohibited while the iterator object exists (in particular, in the
-sequence_of_statements of the loop_statement whose iterator_specification denotes
+Iterate returns a[n] {parallel} iterator object (see 5.5.1) that will generate [a] 
+value{s} for [a] loop parameter{s} (see 5.5.2) designating each node in Container, starting 
+with the first node and moving the cursor according to the successor relation 
+{when used as a forward iterator, and starting with all nodes simultaneously using 
+the Split function to generate cursors for all the iterations of the loop 
+when used as a parallel iterator}. Tampering with the cursors of Container is 
+prohibited while the iterator object exists (in particular, in the 
+sequence_of_statements of the loop_statement whose iterator_specification denotes 
 this object). The iterator object needs finalization.
 
 Modify A.18.6(51.1/3)
@@ -681,16 +815,16 @@
 
 Modify A.18.6(94.2/3)
 
- Iterate returns a {parallel} reversible iterator object (see 5.5.1) that will
- generate [a] value{s} for [a] loop parameter{s} (see 5.5.2) designating each
- node in Container, starting with the first node and moving the cursor according
- to the successor relation when used as a forward iterator, and starting with the
- last node and moving the cursor according to the predecessor relation when used
- as a reverse iterator {, and starting with all notes simultaneously using the
- First and Jump functions to generate cursors for all the iterations of the loop
- when used as a parallel iterator}. Tampering with the cursors of Container is
- prohibited while the iterator object exists (in particular, in the
- sequence_of_statements of the loop_statement whose iterator_specification denotes
+ Iterate returns a {parallel} reversible iterator object (see 5.5.1) that will 
+ generate [a] value{s} for [a] loop parameter{s} (see 5.5.2) designating each 
+ node in Container, starting with the first node and moving the cursor according 
+ to the successor relation when used as a forward iterator, and starting with the 
+ last node and moving the cursor according to the predecessor relation when used 
+ as a reverse iterator {, and starting with all nodes simultaneously using the 
+ Split function to generate cursors for all the iterations of the loop 
+ when used as a parallel iterator}. Tampering with the cursors of Container is 
+ prohibited while the iterator object exists (in particular, in the 
+ sequence_of_statements of the loop_statement whose iterator_specification denotes 
  this object). The iterator object needs finalization.
 
 Modify A.18.6(94.3/3)
@@ -700,18 +834,17 @@
 
 Modify A.18.6(94.4/3)
 
-If Start is not No_Element and does not designate an item in Container, then
-Program_Error is propagated. If Start is No_Element, then Constraint_Error is
-propagated. Otherwise, Iterate returns a {parallel} reversible iterator object
-(see 5.5.1) that will generate [a] value{s} for [a] loop parameter{s} (see 5.5.2)
-designating each node in Container, starting with the node designated by Start
-and moving the cursor according to the successor relation when used as a forward
-iterator, or moving the cursor according to the predecessor relation when used as
-a reverse iterator {, or all nodes simulataneously starting with the node
-designated by Start and obtaining the other cursors via calls to Jump when used
-as a parallel iterator}. Tampering with the cursors of Container is prohibited
-while the iterator object exists (in particular, in the sequence_of_statements
-of the loop_statement whose iterator_specification denotes this object). The
+If Start is not No_Element and does not designate an item in Container, then 
+Program_Error is propagated. If Start is No_Element, then Constraint_Error is 
+propagated. Otherwise, Iterate returns a {parallel} reversible iterator object 
+(see 5.5.1) that will generate [a] value{s} for [a] loop parameter{s} (see 5.5.2) 
+designating each node in Container, starting with the node designated by Start 
+and moving the cursor according to the successor relation when used as a forward 
+iterator, or moving the cursor according to the predecessor relation when used as 
+a reverse iterator {, or all nodes simultaneously using the Split function when used 
+as a parallel iterator}. Tampering with the cursors of Container is prohibited 
+while the iterator object exists (in particular, in the sequence_of_statements 
+of the loop_statement whose iterator_specification denotes this object). The 
 iterator object needs finalization.
 
 Modify A.18.8(49.1/3)
@@ -726,14 +859,14 @@
 
 Modify A.18.8(85.2/3)
 
-Iterate returns a[n] {parallel} iterator object (see 5.5.1) that will generate
-[a] value{s} for [a] loop parameter{s} (see 5.5.2) designating each element in
-Container, starting with the first element and moving the cursor according to the
-successor relation {when used as a forward iterator, and starting with all nodes
-simultaneously using the First and Jump functions to generate cursors for all the
-iterations of the loop when used as a parallel iterator. Tampering with the
-cursors of Container is prohibited while the iterator object exists (in
-particular, in the sequence_of_statements of the loop_statement whose
+Iterate returns a[n] {parallel} iterator object (see 5.5.1) that will generate 
+[a] value{s} for [a] loop parameter{s} (see 5.5.2) designating each element in 
+Container, starting with the first element and moving the cursor according to the 
+successor relation {when used as a forward iterator, and starting with all nodes 
+simultaneously using the Split function to generate cursors for all the 
+iterations of the loop when used as a parallel iterator.} Tampering with the 
+cursors of Container is prohibited while the iterator object exists (in 
+particular, in the sequence_of_statements of the loop_statement whose 
 iterator_specification denotes this object). The iterator object needs finalization.
 
 Modify A.18.9(61.1/3)
@@ -753,16 +886,16 @@
 
 Modify A.18.9(113.2/3)
 
-Iterate returns a {parallel} reversible iterator object (see 5.5.1) that will
-generate [a] value{s} for [a] loop parameter{s} (see 5.5.2) designating each element
-in Container, starting with the first element and moving the cursor according to
-the successor relation when used as a forward iterator, and starting with the
-last element and moving the cursor according to the predecessor relation when
-used as a reverse iterator {, and starting with all notes simultaneously using the
- First and Jump functions to generate cursors for all the iterations of the loop
- when used as a parallel iterator}. Tampering with the cursors of Container is
- prohibited while the iterator object exists (in particular, in the
- sequence_of_statements of the loop_statement whose iterator_specification
+Iterate returns a {parallel} reversible iterator object (see 5.5.1) that will 
+generate [a] value{s} for [a] loop parameter{s} (see 5.5.2) designating each element 
+in Container, starting with the first element and moving the cursor according to 
+the successor relation when used as a forward iterator, and starting with the 
+last element and moving the cursor according to the predecessor relation when 
+used as a reverse iterator {, and starting with all nodes simultaneously using the 
+ Split function to generate cursors for all the iterations of the loop 
+ when used as a parallel iterator}. Tampering with the cursors of Container is 
+ prohibited while the iterator object exists (in particular, in the 
+ sequence_of_statements of the loop_statement whose iterator_specification 
  denotes this object). The iterator object needs finalization.
 
 Modify A.18.9(113.3/3)
@@ -772,18 +905,17 @@
 
 Modify A.18.9(113.4/3)
 
-If Start is not No_Element and does not designate an item in Container, then
-Program_Error is propagated. If Start is No_Element, then Constraint_Error is
-propagated. Otherwise, Iterate returns a {parallel} reversible iterator object
-(see 5.5.1) that will generate [a] value{s} for [a] loop parameter{s} (see 5.5.2)
-designating each element in Container, starting with the element designated by
-Start and moving the cursor according to the successor relation when used as a
-forward iterator, or moving the cursor according to the predecessor relation when
-used as a reverse iterator {, or all nodes simulataneously starting with the node
-designated by Start and obtaining the other cursors via calls to Jump when used
-as a parallel iterator}. Tampering with the cursors of Container is prohibited
-while the iterator object exists (in particular, in the sequence_of_statements
-of the loop_statement whose iterator_specification denotes this object). The
+If Start is not No_Element and does not designate an item in Container, then 
+Program_Error is propagated. If Start is No_Element, then Constraint_Error is 
+propagated. Otherwise, Iterate returns a {parallel} reversible iterator object 
+(see 5.5.1) that will generate [a] value{s} for [a] loop parameter{s} (see 5.5.2) 
+designating each element in Container, starting with the element designated by 
+Start and moving the cursor according to the successor relation when used as a 
+forward iterator, or moving the cursor according to the predecessor relation when 
+used as a reverse iterator {, or all nodes simultaneously using the Split function 
+when used as a parallel iterator}. Tampering with the cursors of Container is prohibited 
+while the iterator object exists (in particular, in the sequence_of_statements 
+of the loop_statement whose iterator_specification denotes this object). The 
 iterator object needs finalization.
 
 Modify A.18.10(44/3)
@@ -803,14 +935,14 @@
 
 Modify A.18.10(157/4)
 
-Iterate returns a[n] {parallel} iterator object (see 5.5.1) that will generate
-[a] value{s} for [a] loop parameter{s} (see 5.5.2) designating each element node
+Iterate returns a[n] {parallel} iterator object (see 5.5.1) that will generate 
+[a] value{s} for [a] loop parameter{s} (see 5.5.2) designating each element node 
 in Container, starting from with the root node and proceeding in a depth-first order
-{when used as a forward_iterator, and starting with all nodes
-simultaneously using the First and Jump functions to generate cursors for all the
-iterations of the loop when used as a parallel iterator}. Tampering with the
-cursors of Container is prohibited while the iterator object exists (in particular,
-in the sequence_of_statements of the loop_statement whose iterator_specification
+{when used as a forward_iterator, and starting with all nodes 
+simultaneously using the Split function to generate cursors for all the 
+iterations of the loop when used as a parallel iterator}. Tampering with the 
+cursors of Container is prohibited while the iterator object exists (in particular, 
+in the sequence_of_statements of the loop_statement whose iterator_specification 
 denotes this object). The iterator object needs finalization.
 
 Modify A.18.10(158/3)
@@ -820,18 +952,17 @@
 
 Modify A.18.10(159/3)
 
-If Position equals No_Element, then Constraint_Error is propagated. Otherwise,
-Iterate_Subtree returns a[n] {parallel} iterator object (see 5.5.1) that will
-generate [a] value{s} for [a] loop parameter{s} (see 5.5.2) designating each
-element in the subtree rooted by the node designated by Position, starting from
-with the node designated by Position and proceeding in a depth-first order
-{when used as a forward iterator, or or all nodes simulataneously starting from
- the element in the subtree rooted by the node designated by Position, and obtaining
- the other cursors via calls to Jump when used as a parallel iterator}. If Position
- equals No_Element, then Constraint_Error is propagated. Tampering with the cursors
- of the container that contains the node designated by Position is prohibited while
- the iterator object exists (in particular, in the sequence_of_statements of the
- loop_statement whose iterator_specification denotes this object). The iterator
+If Position equals No_Element, then Constraint_Error is propagated. Otherwise, 
+Iterate_Subtree returns a[n] {parallel} iterator object (see 5.5.1) that will 
+generate [a] value{s} for [a] loop parameter{s} (see 5.5.2) designating each 
+element in the subtree rooted by the node designated by Position, starting from 
+with the node designated by Position and proceeding in a depth-first order 
+{when used as a forward iterator, or all nodes simultaneously using the Split 
+ function when used as a parallel iterator}. If Position 
+ equals No_Element, then Constraint_Error is propagated. Tampering with the cursors 
+ of the container that contains the node designated by Position is prohibited while 
+ the iterator object exists (in particular, in the sequence_of_statements of the 
+ loop_statement whose iterator_specification denotes this object). The iterator 
  object needs finalization.
 
 
@@ -845,6 +976,26 @@
 sequence_of_statements of a parallel loop are treated as though they are all
 executing as the task that encountered the parallel construct.
 
+Add after D.16 (5/3)
+
+   type Iteration_Count is range 0 .. implementation-defined;
+   for Iteration_Count'Size use implementation-defined;
+
+   type Split_Count is range 0 .. implementation-defined;
+
+   function Advised_Split_Count
+     (Iterations :  Iteration_Count) return Split_Count
+       witn Non_Blocking => False;
+
+Add after D.16 (8/3)
+
+The Advised_Split_Count function accepts a parameter that indicates the number
+of iterations associated with a parallel loop, and returns a recommended value 
+for the number of loop parameter objects to be associated with a parallel loop 
+statement. Such a value is intended to be passed as an actual for the 
+Advised_Split parameter of the Split operation associated with a parallel iterator 
+object (See 5.5.1).
+
 !discussion
 
 There is a continuing trend of exponential growth of computational
@@ -900,7 +1051,8 @@
 respect to each other, but in parallel with the calculation of X. Note
 that the compiler, using the rules specified in AI12-0079-1, may
 complain if the parallel sequences might have conflicting global
-side-effects.
+side-effects, or if the parallel sequences might have Potentially Blocking
+operations.
 
 The parallel block construct is flexible enough to support recursive usage as
 well, such as:
@@ -943,10 +1095,17 @@
 statement in a parallel block, it could be the subject of a separate AI.
 
 We considered what the semantics might be for a parallel block if the parallel
-keyword were absent. This might be a good syntactic construct to use for
+keyword were absent. This might be a good syntactic construct to use for 
 supporting coroutines, for example. Rather than deal with that question in this
 AI, we leave that for consideration in separate AI's.
 
+We considered whether blocking calls should be allowed in a parallel block
+statement. We felt that allowing that could add significant complexity for 
+the implementor, as well as introduce safety concerns about potential deadlocking.
+While such a capability is possible, it was felt that it should be disallowed
+for now. If the demand and need is felt in the future, it could be added then,
+but it is better to not standardize that capability until we know it is needed.
+
 Parallel Loops
 --------------
 
@@ -980,6 +1139,38 @@
 reduction however, is to generate a result value. Iteration is a means to
 achieve that end, but a reduction expression seems better suited since it is
 designed to produce a result value.
+
+We extended the parallel loop capability to work with containers as well as arrays,
+since there could be a need to iterate in parallel over any of the standard
+containers. Containers such as vectors are obvious candidates for parallelisation,
+since it is easy to conceptually think of a vector as a being splittable into
+a number of smaller vectors, and then applying a divide and conquer approach to
+the vector subsets. However, even a sequentially accessed container such as a 
+linked list can be iterated in parallel, if cursors for each parallel executor
+can be obtained prior to execution of the loop. This typically involves iterating
+once through the container to obtain the cursors, but can still be benefit from
+parallel processing if the amount of time to process each node in the loop is
+significantly greater than the amount of time needed to iterate through the list.
+
+Sometimes there are loops that need initialization or finalization for each
+executor, that might be too expensive to apply for each iteration, but would be
+worthwhile if applied once per chunk of execution. An example might be where
+a file needs to be opened for each executor where the loop writes results to
+the file, and after the executor completes its chunk, the file needs to be closed.
+Other possible uses include memory allocation for temporary data structures.
+
+Such loops would require manual chunking, where the user code explicitly calls
+the Split function of a Parallel iterator to obtain the Chunk_Array object that
+normally the implementation would request. This allows the user to express the 
+parallelism more explicitly by writing an outer loop that iterates through the
+number of chunks and an inner loop that iterates through the elements of each chunk.
+
+Since this capability exists for the containers, as all the containers have an
+Iterate primitive that return a parallel iterator object that can be used to
+obtain a chunk array, it was felt the same capability should exist for discrete
+types, so the package Ada.Discrete_Chunking was added to this AI, which simply
+creates a parallel iterator and calls its Split operation to obtain a chunk array
+that can be used with any given discrete type.
 
 !ASIS
 

Questions? Ask the ACAA Technical Agent