Version 1.6 of ai05s/ai05-0193-1.txt

Unformatted version of ai05s/ai05-0193-1.txt version 1.6
Other versions for file ai05s/ai05-0193-1.txt

!standard 13.11(16)          10-06-06 AI05-0193-1/03
!standard 13.11(21)
!standard 13.11.1 (0)
!standard 13.11.1 (1)
!standard 13.11.1 (2)
!standard 13.11.1 (3)
!class amendment 09-11-03
!status Amendment 201Z 09-11-30
!status ARG Approved 10-0-1 09-11-08
!status work item 09-11-03
!status received 09-06-16
!priority Low
!difficulty Easy
!qualifier Omission
!subject Alignment of allocators
!summary
Ada implementations may request more strictly aligned data for allocators. In addition, the attribute Max_Alignment_For_Allocation is added.
!problem
In the case of an allocator of access type whose Storage_Pool is user-defined, RM 13.11(16) completely specifies the value of the Alignment parameter passed in the associated call to Allocate.
This may be inappropriate in some cases. If an Ada implementation chooses to allocate space for additional (typically contiguous) data, the alignment requirements of this additional data may be stricter than the specified Alignment value. In this case, the implementation should have the freedom to pass in an Alignment value that reflects this requirement.
Consider the following example:
type T is access String; for T'Storage_Pool use ... ; X : T := new String'("abc");
In the case of an access type whose designated subtype is an unconstrained array subtype, some implementations prepend contiguous dope information to the allocated array. String'Alignment is typically 1. If the dope information contains values of the array type's index type(s), then the alignment requirement of this dope information might reasonably be that of the most strictly aligned index type. The given example might be easier to implement if the implementation were allowed to pass Integer'Alignment instead of String'Alignment as the Alignment parameter in the call to Allocate associated with the allocator.
As another example, consider the case of an implementation which (for whatever reason - finalization or deallocation) chooses to maintain a linked list of the allocated objects associated with an access type. Suppose further that the implementation chooses to implement this by prepending contiguous linkage fields to each allocated object. If the language definition requires passing in an Alignment value less than System.Address'Alignment, this requirement can be inconvenient.
As a third example, consider the case of an allocated coextension which has a stricter alignment requirement than that of the access-discriminant-bearing "owner" type.
The Max_Size_In_Storage_Elements attribute was designed to cope with all of these issues as they relate to the value of the Size_In_Storage_Elements parameter value that is passed to Allocate. An analogous attribute is needed for the Alignment parameter.
!proposal
(see wording)
!wording
In the Implementation Requirements added by AI05-0107-1 (which replaces paragraph 13.11(16)), replace
The Alignment parameter is D'Alignment if D is a specific type, and otherwise is the alignment of the specific type identified by the tag of the object being created.
with
The Alignment parameter is at least D'Alignment if D is a specific type, and otherwise is at least the alignment of the specific type identified by the tag of the object being created. The Alignment parameter is no more than D'Max_Alignment_For_Allocation.
Completely replace 13.11.1 with
13.11.1 Storage Allocation Attributes
The Max_Size_In_Storage_Elements and Max_Alignment_For_Allocation attributes may be useful in writing user-defined pool types.
Static Semantics
For every subtype S, the following attributes are defined:
S'Max_Size_In_Storage_Elements
Denotes the maximum value for Size_In_Storage_Elements that could be requested by the implementation via Allocate for an access type whose designated subtype is S. The value of this attribute is of type universal_integer.
S'Max_Alignment_For_Allocation
Denotes the maximum value for Alignment that could be requested by the implementation via Allocate for an access type whose designated subtype is S. The value of this attribute is of type universal_integer.
For a type with access discriminants, if the implementation allocates space for a coextension in the same pool as that of the object having the access discriminant, then these attributes account for any calls on Allocate that could be performed to provide space for such coextensions.
Update Annex K accordingly. [This is done automatically; we generally don't mention changes to Annex K, L, M, P, and Q unless they don't appear anywhere else. - ED.]
!discussion
We mention the lower bound on the value of the Alignment parameter mainly to explain the purpose of the Alignment parameter. We could have used vaguer wording like that used for the Size_In_Storage_Elements parameter:
The Size_In_Storage_Elements parameter indicates the number of storage elements to be allocated, and is no more than D'Max_Size_In_Storage_Elements, where D is the designated subtype.
But such wording would have the effect of eliminating any requirements on the parameter (in particular those discussed in AI05-0116-1), and that is not intended by this AI.
The phrase "associated with these discriminants" is intended to include the case of a coextension of a coextension.
!corrigendum 13.11(21)
@Comment{A partial change intended to force a conflict; the real text is found in the conflict file. This only changes 13.11(21.5/3).}
Replace the paragraph:
For one of the calls of Allocate described above, P (equivalent to T'Storage_Pool) is passed as the Pool parameter. The Size_In_Storage_Elements parameter indicates the number of storage elements to be allocated, and is no more than D'Max_Size_In_Storage_Elements, where D is the designated subtype of T. The Alignment parameter is D'Alignment if D is a specific type, and otherwise is the alignment of the specific type identified by the tag of the object being created. The result returned in the Storage_Address parameter is used as the address of the allocated storage, which is a contiguous block of memory of Size_In_Storage_Elements storage elements. Any exception propagated by Allocate is propagated by the construct that contained the call.
by:
For one of the calls of Allocate described above, P (equivalent to T'Storage_Pool) is passed as the Pool parameter. The Size_In_Storage_Elements parameter indicates the number of storage elements to be allocated, and is no more than D'Max_Size_In_Storage_Elements, where D is the designated subtype of T. The Alignment parameter is at least D'Alignment if D is a specific type, and otherwise is at least the alignment of the specific type identified by the tag of the object being created. The Alignment parameter is no more than D'Max_Alignment_For_Allocation. The result returned in the Storage_Address parameter is used as the address of the allocated storage, which is a contiguous block of memory of Size_In_Storage_Elements storage elements. Any exception propagated by Allocate is propagated by the construct that contained the call.
!corrigendum 13.11.1(0)
Replace the paragraph:
The Max_Size_In_Storage_Elements Attribute
by:
Storage Allocation Attributes
!corrigendum 13.11.1(1)
Replace the paragraph:
The Max_Size_In_Storage_Units attribute is useful in writing user-defined pool types.
by:
The Max_Size_In_Storage_Units and Max_Alignment_For_Allocation attributes may be useful in writing user-defined pool types.
!corrigendum 13.11.1(2)
Replace the paragraph:
For every subtype S, the following attribute is defined:
by:
For every subtype S, the following attributes are defined:
!corrigendum 13.11.1(3)
Replace the paragraph:
S'Max_Size_In_Storage_Elements
Denotes the maximum value for Size_In_Storage_Elements that could be requested by the implementation via Allocate for an access type whose designated subtype is S. For a type with access discriminants, if the implementation allocates space for a coextension in the same pool as that of the object having the access discriminant, then this accounts for any calls on Allocate that could be performed to provide space for such coextensions. The value of this attribute is of type universal_integer.
by:
S'Max_Size_In_Storage_Elements
Denotes the maximum value for Size_In_Storage_Elements that could be requested by the implementation via Allocate for an access type whose designated subtype is S. The value of this attribute is of type universal_integer.

S'Max_Alignment_For_Allocation
Denotes the maximum value for Alignment that could be requested by the implementation via Allocate for an access type whose designated subtype is S. The value of this attribute is of type universal_integer.

For a type with access discriminants, if the implementation allocates space for a coextension in the same pool as that of the object having the access discriminant, then these attributes account for any calls on Allocate that could be performed to provide space for such coextensions.

!ACATS test
Create an ACATS C-Test to test the new attribute.
!appendix

From: Steve Baird
Sent: Tuesday, June 16, 2009  6:09 AM

[Posted version /01 of this AI. - ED]

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

From: Tucker Taft
Sent: Tuesday, June 16, 2009  7:09 AM

I agree with this problem and your proposed solution.
I see no need for specifying a minimum alignment, since it is trivial to round
up to a greater alignment.  On the other hand, if a storage allocator is
suddenly handed a bigger alignment than it was prepared for, that could be a
real pain, so I agree with defining an attribute that specifies the max.  It
might also be nice to have a value in package Standard that specifies the
maximum value that this attribute would ever have, so that simple allocators can
simply return everything with that maximum alignment, and ignore the alignment
parameter completely.

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

From: Bob Duff
Sent: Tuesday, June 16, 2009  9:50 AM

> It might also be nice to have
> a value in package Standard that specifies the maximum
                     ^^^^^^^^
Maybe you mean package System?

> value that this attribute would ever have, so that simple allocators
> can simply return everything with that maximum alignment, and ignore
> the alignment parameter completely.

GNAT supports crazy stuff like:

    for T'Alignment use 2**25;

so such a "simple allocator" would not be useful in GNAT.  Doesn't mean such a
constant shouldn't exist in the language.

Maybe we want (instead or in addition) the max alignment the impl will pass to
an allocator when there are no user-specified Alignment clauses.

Which might not be quite the same as the max alignment of any type chosen by
default (but that might be useful, too).

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

From: Tucker Taft
Sent: Tuesday, June 16, 2009  10:32 AM

>> It might also be nice to have
>> a value in package Standard that specifies the maximum
>                      ^^^^^^^^
> Maybe you mean package System?

Yes, I meant System.

>> value that this attribute would ever have, so that simple allocators
>> can simply return everything with that maximum alignment, and ignore
>> the alignment parameter completely.
>
> GNAT supports crazy stuff like:
>
>     for T'Alignment use 2**25;

Really?  I could imagine it accepting something like that for a library-level
object's alignment, but for a type that seems very hard to support.

> so such a "simple allocator" would not be useful in GNAT.  Doesn't
> mean such a constant shouldn't exist in the language.
>
> Maybe we want (instead or in addition) the max alignment the impl will
> pass to an allocator when there are no user-specified Alignment clauses.

Yes, I suppose that would be more useful.
It would also be useful to have a maximum supported alignment for user-specified
*subtype* alignment clauses (and perhaps for objects as well).

> Which might not be quite the same as the max alignment of any type
> chosen by default (but that might be useful, too).

Yes, that too.  Sounds like a nice little collection of alignment limits.

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

From: Robert Dewar
Sent: Wednesday, June 17, 2009  5:36 AM

> Really?  I could imagine it accepting something like that for a
> library-level object's alignment, but for a type that seems very hard
> to support.

No, you just allocate extra and waste some space. We have to have this
cirrcuitry anyway to meet existing rules of the language, e.g. when the storage
allocator/stack max alignment does not match. So it is no extra work to trigger
it in silly cases.

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

From: Bob Duff
Sent: Wednesday, June 17, 2009  3:11 PM

> >     for T'Alignment use 2**25;
> Really?

Yup.  ;-)

>...I could imagine it accepting something like that  for a
>library-level object's alignment, but for a type that  seems very hard
>to support.

Well, having been involved in some bug fixing in this area, I guess I'd have to
agree with "hard".  Not terribly efficient, either.

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

Questions? Ask the ACAA Technical Agent