CVS difference for ai05s/ai05-0111-3.txt

Differences between 1.5 and version 1.6
Log of other versions for file ai05s/ai05-0111-3.txt

--- ai05s/ai05-0111-3.txt	2010/11/12 04:22:18	1.5
+++ ai05s/ai05-0111-3.txt	2010/11/18 07:07:35	1.6
@@ -1,4 +1,4 @@
-!standard  4.8(2)                                   10-10-30    AI05-0111-3/04
+!standard  4.8(2)                                   10-11-15    AI05-0111-3/05
 !standard  4.8(3/2)
 !standard  4.8(10.3/2)
 !standard 13.11(16/3)
@@ -40,15 +40,6 @@
 reclaimed with a single operation), and can be used as a building block
 for safer allocations.
-Associated with each subpool is a "dynamic master," similar to the
-"static" masters associated with the execution of various language
-constructs. The dynamic master associated with a subpool is the master
-for all objects residing in the subpool. When a subpool is reclaimed,
-this is analogous to a static master being completed for the objects
-in the subpool.
 Allow the storage pool associated with one or more access types to be
@@ -75,7 +66,7 @@
 Add at the end of 4.8(3/1):
-   The expected type for a *subpool_handle*_name is a descendant of
+   A *subpool_handle*_name is expected to be of any descendant of
    System.Storage_Pools.Subpools.Subpool_Handle, the type used to identify a subpool
    defined in the language-defined package System.Storage_Pools.Subpools (see 13.11.4).
@@ -94,6 +85,25 @@
    subpool object has been deallocated, execution is erroneous; it is likely that
    this check will still detect the problem, but there cannot be a guarentee.)
+Add after 7.6.1(20):
+Implementation Permissions
+The implementation may finalize objects created by allocators for an access type
+whose storage pool supports subpools (see 13.11.4) as if the objects were created
+(in an arbitrary object) at the point where the storage pool was elaborated instead
+of the first freezing point of the access type.
+AARM Ramification: This allows the finalization of such objects to occur later than
+they otherwise would, but still as part of the finalization of the same master.
+AARM Implementation Note: This permission is intended to allow the allocated objects
+to "belong" to the subpool objects and to allow those objects to be finalized at the
+time that the storage pool is finalized (if they are not finalized earlier). This is
+expected to ease implementation, as the objects will only need to belong to the
+subpool and not also the collection.
 Modify 13.11(16/3):
    An allocator of type T {without a subpool_specification} allocates
@@ -198,29 +208,6 @@
 on the pool of the type of the allocator. All requirements on
 the Allocate procedure also apply to Allocate_from_Subpool.
-[Redundant: There is a master associated with the execution of certain
-constructs (see 7.6.1),] called a *construct master*. In addition, each
-subpool has its own unique master, called the *master for the subpool*,
-which is used for the objects allocated from the subpool.
-When an object is created by an allocator and the object is allocated
-from a subpool, then the master of the allocated object (and of any
-parts that are task objects) is the master for the subpool, rather than
-that of the access type's collection. When a subpool is *explicitly
-finalized* (see below), its finalization proceeds by completing any
-tasks dependent on the subpool's master that are waiting at an open
-terminate alternative, waiting for their termination, and then
-finalizing any of the objects allocated from the subpool that still
-exist. After a subpool has been finalized, any storage allocated for
-objects in the subpool can be reclaimed.
-As the first step of finalizing an object of type
-Root_Storage_Pools_with_Subpools, any subpools belonging to the pool
-not previously explicitly finalized are explicitly finalized.
-(A subpool *belongs* to the pool which was passed to the call of
-Set_Pool_of_Subpool for the subpool. The relationship continues until
-the designated object of the subpool handle is finalized.)
 Legality Rules
 If a storage pool that supports subpools is specified as the Storage_Pool for
@@ -252,27 +239,31 @@
 A subpool may be explicitly deallocated using Unchecked_Deallocate_Subpool.
-[Redundant: The *master of an object* is the innermost (construct)
-master that included the elaboration of the object, for an object that
-is part of a declared object. The *master of an object* that is part of
-an object created by an allocator is the master for the subpool if it is
-allocated from a subpool; otherwise it is the (construct) master of the
-ultimate ancestor of the type of the allocator.]
 If Subpool is null, a call on Unchecked_Deallocate_Subpool
-has no effect. Otherwise, a call on Unchecked_Deallocate_Subpool causes
-the subpool designated by Subpool
-to be explicitly finalized (see 13.11.4); followed by a
-Redundant[dispatching] call on
-System.Storage_Pools.Subpools.Deallocate_Subpool (
-   System.Storage_Pools.Subpools.Pool_of_Subpool(Subpool).all, Subpool);
-finally Subpool is set to null.
-It is a bounded error if nonterminable tasks depend
-on the master of the subpool being deallocated. The possible
-effects are as given for the unchecked deallocation of an
-object with a task part (see 13.11.2).
+has no effect. Otherwise, a call on Unchecked_Deallocate_Subpool has
+the following effects:
+* Any tasks allocated from the subpool desigated by Subpool that are
+  waiting at an open terminate alternative are completed (see 9.2);
+* Next, the call waits for any completed tasks allocated from that subpool
+  (including ones completed by the previous bullet) to complete their
+  finalization;
+* Then any of the objects allocated from the subpool that still exist
+  are finalized in an arbitrary order;
+* Now, the following Redundant[dispatching] call is made
+  System.Storage_Pools.Subpools.Deallocate_Subpool (
+      System.Storage_Pools.Subpools.Pool_of_Subpool(Subpool).all, Subpool);
+* Finally, Subpool is set to null.
+It is a bounded error if tasks that are neither completed nor waiting at
+a terminate alternative were allocated from the
+subpool being deallocated. The possible effects are as given for the
+unchecked deallocation of an object with a task part (see 13.11.2).
 Here is a simple but complete implementation of the classic Mark/Release pool
@@ -290,8 +281,7 @@
     type Mark_Release_Pool_Type (Pool_Size : System.Storage_Elements.Storage_Count) is new
         System.Storage_Pools.Subpools.Root_Storage_Pool_with_Subpools with private;
-         Subpool : in out Subpool_Handle
     function Mark (Pool : in out Mark_Release_Pool_Type;
         Storage_Size : System.Storage_Elements.Storage_Count :=
            System.Storage_Elements.Storage_Count'Last) return not null Subpool_Handle;
@@ -479,9 +469,15 @@
 Delete the Block_Size discriminant from 13.11(39/1), and add a comment "As
 defined in 13.11.5".
+Delete the Block_Size discriminant from 13.11(41), and add after it:
+My_Mark : MR_Pool.Subpool_Handle; -- See 13.11.5
-Delete the Block_Size discriminant from 13.11(41).
+Replace 13.11(43):
+My_Mark := Mark(MR_Pool);
+... -- Allocate objects using "new (My_Mark) Designated(...)"
@@ -548,10 +544,10 @@
 directly as part of the pool object, or may be separately allocated and
 managed by the pool.
-Objects allocated into a subpool have a master of that subpool, and will
-be finalized when the subpool is explicitly deallocated (or when the
-entire pool is finalized). This point of finalization has no relationship
-to the point of declaration of the access type, unlike "normal" access types.
+Objects allocated into a subpool will be finalized when the subpool is
+explicitly deallocated. If that never happens, the objects can be finalized
+in the normal place for the access type, or the implementation can finalize
+them when the entire pool is finalized.
 Since the objects allocated into a subpool may be finalized before or after
 the associated access type(s), we have to take care that the objects are
@@ -589,9 +585,7 @@
 that supports subpools.
 Similar implementation complexity would also apply to task dependence. Because of
-this complexity, we chose the simpler model. But we do need to look at some real
-examples to see if the proposed check is too restrictive in practice (for instance,
-access to incomplete types deferred to a body cannot use subpools with this check).
+this complexity, we chose the simpler model.
 The other alternative would be to decouple subpools from the underlying pool. The
 subpool could be required to have a shorter lifetime than the access type (or the
@@ -615,9 +609,9 @@
 could be done at assignments and uses to prevent dangling pointers.
 Creative use of the reference aspect (see AI05-139-2) could make these wrappers
-easy to use. (Unfortunately, the wrappers themselves can't have a reference
+easy to use. Unfortunately, the wrappers themselves can't have a reference
 aspect, as the required access discriminant would prevent useful assignments.
-But a helper function and object could do the job safely.)
+But a helper function and object could do the job safely.
@@ -768,4 +762,119 @@
+From: Randy Brukardt
+Sent: Saturday, October 30, 2010  11:11 PM
+Attached find the /04 update for the subpool proposal.
+I made the changes requested by Brad and by the ARG discussion, except for 2:
+I didn't follow Bob's two subtype proposal because it would complicate the use
+for users; I used direct "not null" instead.
+I didn't follow Tucker's fully private example suggestion, because that would
+make the type not a storage pool to clients, meaning they couldn't use it to
+specify 'Storage_Pool, making it useless. I was able to do the rest of the
+rearranging, so I think it is better separated into client and implementation
+I also did the following three changes:
+Added a Default_Subpool_for_Pool routine. Otherwise, the implementation would
+not know what subpool to use as the master for the allocated objects. That would
+be bad.
+Also reworded Unchecked_Subpool_Deallocate to handle the null subpool case
+(can't use not null there as the handle is nulled out by this call).
+Also noticed missing System prefixes in the example.
+Finally, added discussion of possible safer ways to use this, as requested by
+Brad. It's in the discussion, not the problem.
+From: Robert Dewar
+Sent: Monday, November 8, 2010  3:19 AM
+> 1) 4.8(10.3/2) AARM Reason: "it is likely that this check will still
+> detect the problem,"
+> "Likely" seems a bit strong here, as it implies that most vendors will
+> implement this, when that remains to be seen. I suggest replacing
+> "likely" with "possibly".
+I would keep likely, the immediate issue is really whether GNAT implements
+this or not, so just get the answer to that question!
+From: Randy Brukardt
+Sent: Monday, November 8, 2010  5:51 PM
+Bob said at the meeting that he wants to implement it in GNAT whether or not it
+gets standardized. That's a pretty strong endorsement!
+Anyway, this was the one place where I didn't understand Brad's comment and did
+not act on it in the next draft (written Saturday night and discussed on Sunday
+at the meeting). None of this is interesting if it isn't implemented, and this
+note is discussing a runtime check on a subpool handle. If there aren't any
+subpool handles, there surely isn't any check (and if there are, there surely is
+a check, it's easy to implement and an allocator that fails the check is
+nonsense), so I don't understand what the relevance of implementation is.
+Some background. This AARM note is applied to the runtime check that a subpool
+handle represents a subpool of the pool of the access type being allocated. The
+allocator would be nonsense if it was allocating objects from some other *pool*
+than the one defined for the type. Thus there is a runtime check (all subpool
+handles being equivalent as far as the Ada implementation is concerned).
+The AARM note is discussing the issue of allocating from a "dangling" subpool
+handle; that is, a subpool handle for a subpool that has already been
+deallocated. It was intended to note that this pool check will also "likely"
+detect a dangling subpool handle.
+Whether the check can detect a dangling subpool handle depends on the
+implementation of the pool (something totally under the control of the pool
+implementor, not the Ada implementer). When a subpool is deallocated, the Ada
+implementation is required to sever the connection between the subpool and the
+pool, thus the check will automatically fail for a dangling subpool so long as
+the subpool object still exists. (This is easily implemented by simply setting
+the connection to null.) Therefore, the check will always detect dangling
+handles if the subpool objects are statically part of the pool object (as in the
+example in the AI). However, if the subpool objects are themselves deallocated
+when the subpool is deallocated, then the subpool handle is really dangling in
+an Ada sense and the check is technically doing something erroneous. (That's OK,
+because the use of the subpool handle as an allocator is also erroneous in that
+case, so there is no additional erroneousness created by the check.) Still, the
+check is likely to detect a problem, as the implementation will have broken the
+connection before the memory was deallocated. Thus, practically, the check would
+only pass (that is, fail to detect the error) if the same memory was allocated
+as another subpool object for the same pool before the check is made. If it is
+allocated to some other kind of entity, it is highly unlikely that it would have
+the right memory contents for the check to pass.
+This is too much explanation for an AARM note. It's probably even too much
+explanation for the !discussion section of the AI; but it is just right in the
+!appendix, which is why I just spent 10 minutes writing it up.
+From: Bob Duff
+Sent: Monday, November 8, 2010  6:00 PM
+Thank you.  Good explanation.  So "likely" is correct.
+From: Tucker Taft
+Sent: Monday, November 8, 2010  6:11 PM
+Your discussion makes sense to me.
+The run-time check for whether the
+subpool is from the right pool is not optional.
+The "likeliness" issue is merely based on the vagaries of reusing storage, etc.,
+and as Randy points out, is in (partial) control of the subpool implementor, not
+the Ada implementor.

Questions? Ask the ACAA Technical Agent