Version 1.1 of ai12s/ai12-0415-1.txt

Unformatted version of ai12s/ai12-0415-1.txt version 1.1
Other versions for file ai12s/ai12-0415-1.txt

!standard 9.10.1(20/5)          20-12-03 AI12-0415-1/01
!standard 9.10.1(21/5)
!standard 9.10.1(23/5)
!class Amendment 20-12-03
!status work item 20-12-03
!status received 20-12-03
!priority Low
!difficulty Easy
!subject Parallel_Calls aspect for types
!summary
We generalize the aspect Parallel_Calls (see 9.10.1) to apply to immutably limited or formal limited types, and to access-to-object types. If specified for an immutably or formal limited type, this means that Parallel_Calls applies to all primitive subprograms of the type, with the exception of the Initialize and Finalize operations for limited controlled types. If specified for an access type, it means that the storage pool is a standard storage pool, or that Parallel_Calls applies to the Allocate, Deallocate, and Storage_Size operations of the type of the access type's storage pool.
!problem
In analyzing the side effects of allocation and deallocation on storage pool objects. the issue arose of whether such effects are safe from conflicts due to unsynchronized references to shared variables. It has generally been presumed that allocation and deallocation are thread safe for "standard" storage pools, meaning that allocators for the same access type (with such a storage pool) are safe even if they occur concurrently in different threads of control. But there is no way to specify that a user-defined storage pool has a similar level of thread safety.
Recognizing this problem for user-defined storage pools led to a recognition that the problem is more general, in that there is no way to declare that an object of a given type can safely be operated on concurrently from multiple threads. Note that language-defined subprograms are required (in Annex A(3/5)) to provide thread safety, but only if the objects being operated on are different, so this is really talking about side effects on globals, if any. And of course protected operations and task entries can safely be called concurrently on the same protected/task object (though even with these there is still the possibility that such concurrent calls conflict because they have other by-reference or by-access parameters which are not themselves "synchronized" in any sense).
!proposal
We propose to allow the specification of the aspect Parallel_Calls (see 9.10.1) on a type whose full type is an immutably limited type, a formal limited private type or extension, or an access-to-object type (including a formal access type).
If the Parallel_Calls aspect is True for an immutably or formal limited type, then it is equivalent to specifying Parallel_Calls => True for every primitive subprogram of the type, other than Initialize and Finalize in the case of a descendant of Limited_Controlled.
If the Parallel_Calls aspect is specified True for an access-to-object type then it must either have a standard storage pool, or the aspect Parallel_Calls => True must apply to the subprograms Allocate, Deallocate, and Storage_Size of its storage pool type.
Modify 9.10.1(20/5-21/5):
All_Parallel_Conflict_Checks
This policy includes the restrictions imposed by the Known_Parallel_Conflict_Checks policy, and in addition disallows a parallel construct from reading or updating a variable that is global to the construct, unless it is a synchronized object{, the reading or updating is performed using a subprogram for which Parallel_Calls is True}, or unless the construct is a parallel loop, and the global variable is a part of a component of an array denoted by an indexed component with at least one index expression that statically denotes the loop parameter of the loop_parameter_specification or the chunk parameter of the parallel loop.
All_Tasking_Conflict_Checks
This policy includes the restrictions imposed by the Known_Tasking_Conflict_Checks policy, and in addition disallows a task body from reading or updating a variable that is global to the task body, unless it is a synchronized object{, or the reading or updating is performed using a subprogram for which Parallel_Calls is True}.
Modify RM 9.10.1(23/5):
For a subprogram, {an access-to-object type, a type whose full type is immutably limited, or a formal limited private type or extension,} the following language-defined representation aspect may be specified.
Add after RM 9.10.1(25/5):
Specifying the Parallel_Calls aspect to be True for an access-to-object type indicates that the storage pool for the access type is a standard storage pool, or that Parallel_Calls is True for the Allocate, Deallocate, and Storage_Size primitive subprograms of the type of the access type's storage pool.
Specifying the Parallel_Calls aspect to be True for a limited (or formal limited) type indicates that the full (or actual) type is a protected or task type, or that the Parallel_Calls aspect is True for all primitive subprograms of the type (or all visible primitives of the formal type), except for the Initialize and Finalize procedures in the case of a limited controlled type.
!discussion
We considered defining a new aspect for this purpose, but felt it was better to build on the Parallel_Calls aspect, as it would be confusing to have two closely related concepts using different aspects. We considered changing the name of the aspect to "Synchronizing" but felt that might imply that some kind of lock was involved, when really all we are promising is that parallel calls are safe.
We make an exception for Initialize and Finalize as these are generally never invoked implicitly in parallel for a limited controlled type. The user might invoke one of these explicitly, but there is generally no guarantee that concurrent finalization or initialization even of a "trivial" controlled object is guaranteed to be implemented in a thread safe manner.
We presume that all operations on protected and task types support parallel calls, though it is conceivable that a user could construct one that would be unsafe, but we see no reason to try to account for such an unlikely special case. A friendly implementation could provide a warning if it were to detect such a situation.
!examples
type Lim_I_F is limited interface; procedure Update(X : in out Lim_I_F) is abstract;
generic type Formal_Acc is access Integer with Parallel_Calls; -- Actual type must have standard storage pool -- or have a user-defined storage pool with -- Allocate/Deallocate/Storage_Size with -- Parallel_Calls True.
type Formal_Lim is limited new Lim_I_F with private with Parallel_Calls; -- Actual type must be protected, task, or have a primitive -- Update with Parallel_Calls True.
package Gen is function New_Acc (X : Integer) return Formal_Acc with Parallel_Calls; procedure Double_Update (Y : in out Formal_Lim) with Parallel_Calls; end Gen;
package body Gen is function New_Acc (X : Integer) return Formal_Acc is (new Formal_Acc'(X)); -- This satisfies Parallel_Calls True because -- type Acc has Parallel_Calls True.
procedure Double_Update (Y : in out Formal_Lim) is -- This satisfies Parallel_Calls True because -- either Y is a task or a protected object, -- or procedure Update has Parallel_Calls True. begin Update (Y); Update (Y); end Double_Update; end Gen;
!ASIS
No ASIS effect.
!ACATS test
ACATS B- and C-Tests are needed to check that the new capabilities are supported.
!appendix

****************************************************************


Questions? Ask the ACAA Technical Agent