CVS difference for ai05s/ai05-0111-1.txt
--- ai05s/ai05-0111-1.txt 2008/11/08 03:19:42 1.5
+++ ai05s/ai05-0111-1.txt 2009/02/17 05:53:49 1.6
@@ -1,4 +1,4 @@
-!standard 4.8(2) 08-10-25 AI05-0111-1/03
+!standard 4.8(2) 09-02-15 AI05-0111-1/04
@@ -52,6 +52,11 @@
there are no external references to any of the subpools, the entire set
of mutually-referencing subpools may be reclaimed.
+For any given task, a default subpool may be established for a given
+access type, within a given scope. An allocator without specifying a
+subpool explicitly for the access type will use the innermost
+default subpool specification for the type.
Associated with each subpool is a "dynamic master," similar to the
@@ -71,7 +76,7 @@
2) Dynamic subpool handle
3) Strong object reference
4) Weak object reference
A "static subpool handle" is a counted reference to a subpool
represented by a controlled immutable object declared within a static
master. A "dynamic subpool handle" is an immutable, counted reference
@@ -119,13 +124,18 @@
subpool and an access value designating some object to which the subpool
has access. The reference is "managed" in the sense that if the subpool
is about to be finalized, all weak object references designating the
-subpool are located and set to be null references. For programmatic
-use, a weak object reference can be converted to a strong object
-reference, and from there to a handle and access value, though the
-resulting static handle and access value might be null. Weak object
-references may be assigned from other weak object references or strong
-object references. A weak object reference may be stored anywhere that
-the associated access type is defined.
+subpool are disconnected from the subpool (this can be accomplished
+efficiently using a level of indirection). For programmatic use, a weak
+object reference can be converted to a strong object reference, and from
+there to a handle and access value, though the resulting static handle
+and access value will be null if the weakly referenced pool has been
+finalized. Weak object references may be assigned from other weak object
+references or strong object references. A weak object reference may be
+stored anywhere that the associated access type is defined.
+Subpools with only weak references are made available for reclamation,
+though they will not be reclaimed immediately if free storage is "plentiful"
+(exactly how "plentiful" is defined is TBD).
@@ -133,28 +143,26 @@
then checks are performed on assignment and function return to make sure
that an access value never outlives the subpool containing the object it
designates (the "designated subpool"). On assignment of an access value
-to a stand-alone access object, or to a component of an
-immutably-limited composite object, an accessibility check will be
-performed to ensure that the master of the assigned object has access to
-the designated subpool. On assignment to a component of a composite
-object that is not immutably limited, a check is made that the type of
-the composite object does not outlive the designated subpool (i.e. that
-the master of the composite type has access to the designated subpool).
-This latter rule ensures that on assignment of composite objects, no
-component-by-component accessibility checks need be performed. We make
-an exception for immutably-limited composite types because there is no
-place where an object of such a type could be assignable to another
-object of the type, and hence no place where component-by-component
-checks would be necessary.
-When assigning to OUT or IN OUT parameters, the master of the object is
-presumed to be the innermost master enclosing the call, so the check
-ensures that that master has access to the designated subpool. Similarly
-on function return of an access value, the check is against the
-innermost master enclosing the call. On assignment to a component of an
-immutably-limited return object, the check is against the actual
-eventual master of the return object, since this is known due to the
-build-in-place requirements for such a type.
+to a stand-alone access object, or to a component of a composite object,
+an accessibility check will be performed to ensure that the master of
+the assigned object has access to the designated subpool. This includes
+the case of composite assignment where one or more of the components of
+the object being assigned are such access values.
+When assigning to OUT or IN OUT parameters of an access type, the master
+of the object is presumed to be the innermost master enclosing the call,
+so the check ensures that that master has access to the designated
+subpool. Similarly on function return of an access value, the check is
+against the innermost master enclosing the call. On assignment to a
+component of a composite OUT or IN OUT parameter that is passed by
+reference, the check is against the master of the actual parameter
+(requiring an additional implicit parameter to identify the master,
+analogous to the accessibility level of an access parameter). Similarly,
+on assignment to a component of a composite return object that is built
+in place, the check is against the actual eventual master of the return
+object. If the composite parameter is passed by copy, or the return
+object is not built in place, the check is against the innermost master
+of the call.
@@ -168,7 +176,7 @@
access to it, since only the presence of a static subpool handle can
cause a nested master to have more access than its enclosing master.
This property ensures that most access value manipulations need no
It is only if an assignment or function return is "crossing" a master
having a static subpool handle that any check need be performed.
@@ -177,7 +185,7 @@
required. For example, if the access value came from a formal
parameter, perhaps after following various intermediate indirections, it
is always safe to return it, even if the function did have local masters
-with static subpool handles.
+with static subpool handles.
Note that this means that existing Ada code that takes an access value,
and follows one or more levels of indirection to retrieve another access
@@ -207,7 +215,7 @@
the storage pool is required to provide the Originating_Subpool
operation, it is the underlying Ada implementation that actually
maintains the reference counts associated with subpool handles and
-strong references, and the lists associated with weak references. It
+strong references, and the structures associated with weak references. It
also performs whatever run-time checks are required. One way to think
about it is that the Ada implemention worries about the masters,
while the user code can take over allocation from and reclamation of
@@ -237,22 +245,37 @@
arbitrary directed graph of dependencies between subpools can be reduced
to a forest of strict trees between subpool "combines," simplifying the
job of relative lifetime determination.
+For weak references, we would recommend using an intermediate structure
+that lives as long as there is any weak reference to a given subpool,
+even after the subpool itself is finalized. This intermediate structure
+would have a count of weak references to the subpool, and the subpool
+and this intermediate structure would have pointers to one another.
+When the first weak reference to a subpool is created, this intermediate
+structure could be allocated out of the "main" subpool. It would be
+released back to the main subpool when the last weak reference was
+finalized. When the target subpool was finalized, the intermediate
+structure would be marked so that any future conversions of a weak
+reference to a strong reference would result in null.
In the absence of an explicit subpool specified on an allocator for an
access type with subpools, which subpool should be used? The "original"
-one (i.e. access_type'Storage_Pool). Perhaps we could allow a static
-subpool handle to be marked as a "default allocation handle," and then
-the innermost such handle associated with the storage pool of the access
-type would be used. Obviously the latter would be more flexible, and
-allow existing code to be used without having to annotate existing
-allocators with explicit subpools. On the other hand, it creates many
-possibilities for confusion and bugs, since the identification of the
-handle might be far removed from the actual allocator. Another
-alternative is to base it on the target of the allocator, if it is being
-stored directly into a component of an immutably-limited
+one (i.e. access_type'Storage_Pool). We would recommend allowing a
+static subpool handle to be marked as a "default allocation handle," and
+then the innermost such handle associated with the storage pool of the
+access type would be used. This latter approach would be more flexible,
+and allow existing code to be used without having to annotate existing
+allocators with explicit subpools. On the other hand, it can create
+possibilities for confusion, since the identification of the handle
+might be far removed from the actual allocator. Another alternative is
+to base the subpool on the target of the allocator, if it is being
+stored directly into a component of a subpool-resident object.
+The other major advantage of defining a notion of "default subpool" is
+that implementations could provide a subpool capability without
+extending the syntax of the language.
@@ -308,6 +331,12 @@
the application would notify the caching task on each "significant" use
of the subpool, so the recency of significant use could be determined.
+Alternatively, as we suggested above at the end of the section
+on "SUBPOOL REFERENCES," the implementation could automatically
+defer reclaiming subpools with outstanding weak references, as long as
+free memory is "plentiful." This would eliminate the need for
+each application to have its own "caching" task to accomplish the
@@ -3600,7 +3629,7 @@
From: Tucker Taft
-Sent: Staurday, October 25, 2008 2:02 PM
+Sent: Saturday, October 25, 2008 2:02 PM
I presented some of the ideas associated with per-allocator pools to the "container"
working group recently at a meeting we held to discuss new kinds of containers, and
@@ -3615,5 +3644,38 @@
premature, so you will find a !proposal, a !discussion, and an Example.
[This is version /03 of the AI - Editor.]
+From: Tucker Taft
+Sent: Sunday, February 15, 2009 5:29 PM
+Here is an update to my AI on breaking up a storage pool into "subpools" with
+different allocators for the same access type allocating from different
+subpools. The changes are due to further reflection on comments provided
+by Randy and Steve on an earlier version.
+The main changes are:
+ 1) Composite assignment requires component-by-component
+ accessibility checks for components having a multi-subpool
+ access type (the earlier approach was too limiting).
+ 2) Composite types that are passed by reference that
+ contain multi-subpool access values will need to
+ pass an implicit parameter identifying their master.
+ 3) I have put more emphasis on the notion of a default
+ subpool, so an implementation could provide much
+ of the proposed capability without relying on the extended
+ syntax for allocators.
+ 4) I have recommended that subpools with outstanding
+ weak references not be reclaimed immediately, but
+ rather remain unreclaimed as long as memory is
+ "plentiful," to avoid each application having to
+ provide its own "caching" task to prevent immediate
+ reclamation of such subpools.
+[This is version /04 of the AI - Editor.]
Questions? Ask the ACAA Technical Agent