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

Differences between 1.11 and version 1.12
Log of other versions for file ai05s/ai05-0111-1.txt

--- ai05s/ai05-0111-1.txt	2010/01/09 01:31:29	1.11
+++ ai05s/ai05-0111-1.txt	2010/02/23 22:43:18	1.12
@@ -1,8 +1,11 @@
-!standard  4.8(2)                                   09-11-16    AI05-0111-1/07
+!standard  4.8(2)                                   10-02-23    AI05-0111-1/08
 !standard  4.8(3/2)
-!standard  4.8(5.3/2)
-!standard  5.2(11)
+!standard  4.8(10.1/3)
+!standard 13.11(16/3)
 !standard 13.11.4 (0)
+!standard 13.11.5 (0)
+!standard 13.11.6 (0)
+!standard 13.11.7 (0)
 !class Amendment 08-08-08
 !status work item 08-08-08
 !status received 08-03-12
@@ -41,14 +44,8 @@
 
    X := new (Subpool) T'(ABC);
 
-Subpools may be reclaimed using unchecked-deallocation. The
-finalization of a subpool automatically results in the finalization of
-all elements allocated from the subpool. Program_Error is raised if
-there are any non-terminable task objects in the subpool at the time of
-its finalization.
-
-In the high-integrity annex we provide an alternative to manual
-reclamation of subpools, by using reference counting and additional
+Subpool "handles," and strong and weak references are used to determine when
+it is safe to reclaim a subpool, by using reference counting and additional
 "reachability" checks.  When the reference count drops to zero and
 all task objects in the subpool are terminable, the subpool will be
 automatically reclaimed.  Weak references may be used to forestall the
@@ -70,13 +67,13 @@
 being completed. If a subpool is reclaimed before all the tasks dependent
 on its associated dynamic master are terminable, Program_Error is raised.
 
-In the high-integrity annex, automatic reclamation of a subpool is deferred
+To provide safety, automatic reclamation of a subpool is deferred
 until any tasks dependent on the master are terminable, as with the
 normal exit from a scope with a (static) master.
 
 SUBPOOL REFERENCES
 
-In the high-integrity annex, we define the notion of a "handle" on a
+We define the notion of a reference-counted "handle" on a
 subpool. 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 to
@@ -90,21 +87,22 @@
 language-defined procedure "Allow_Reference (From_Subpool, To_Subpool),"
 where the subpools are identified by static handles.
 
-In the high-integrity annex, we use the term "reachable" to mean that
+We use the term "reachable" to mean that
 there is a chain of handles connecting one master (or its associated
-pool) to another master/pool. A master/pool is always reachable from
+pool) to another master/subpool. A master/subpool is always reachable from
 itself. Because handles are immutable, the set of masters/pools
-reachable from a given master/pool never shrinks, as long as the
-master/pool exists.
+reachable from a given master/subpool never shrinks, as long as the
+master/subpool exists.
 
-The basic safety rule is that a master/pool is never automatically
+The basic safety rule is that a master/subpool is never automatically
 reclaimed if it is reachable from a static master, or from a pool
 containing a non-terminable task. What this means is that it is "safe"
 (in the sense of avoiding dangling references) for an access value
 stored in an object in master/pool A to designate another object in a
-master/pool B so long as master/pool B is reachable from master/pool A.
+master/subpool B so long as master/subpool B is reachable from
+master/subpool A.
 
-In the high-integrity annex, we also define "strong" and "weak" references.
+For flexibility, we also define "strong" and "weak" references.
 A "strong object reference" is a combination of a counted reference on a
 subpool and an access value designating some object reachable from that
 subpool. For programmatic use, a strong object reference can be
@@ -137,7 +135,7 @@
 
 REACHABILITY CHECKS
 
-In the high-integrity annex, additional "reachability" checks are defined.
+To ensure safety, "reachability" checks are defined.
 If an access type is associated with a storage pool that has subpools,
 then checks are performed on assignment and function return to make sure
 that an access value never outlives the subpool containing the object it
@@ -170,68 +168,33 @@
   allocator ::=
      new [subpool_specification] subtype_indication
    | new [subpool_specification] qualified_expression
-
-  subpool_specification ::= '(' subpool_name ')'
 
-  subpool_name ::= name | implicit_dereference
+  subpool_specification ::= '(' *subpool_handle*_name ')'
 
 
 Add at the end of 4.8(3/1):
-
-   The expected type for a subpool_name is Root_Storage_Pool'Class, the
-   class-wide type for the type Root_Storage_Pool defined in the
-   language-defined package System.Storage_Pools (see 13.11).
-
-
-Add after 4.8(5.3/2):
-
-   If a subpool_specification is provided, the subpool_name shall denote
-   a variable storage pool object whose accessibility level shall not be
-   statically deeper than that of the type of the allocator. If the
-   type of the allocator is a pool-specific access type (see 3.10), then
-   that type shall have a user-defined Storage_Pool attribute that
-   statically denotes a storage pool variable, and the subpool_name
-   shall be a dereference (explicit or implicit) of an access value
-   whose type is also pool-specific and whose Storage_Pool attribute
-   statically denotes that same storage pool variable.
 
-     [AARM Note: These rules ensure that the storage pool lives at least
-     as long as the access type (in the absence of unchecked
-     deallocation of the storage pool), and in the pool-specific case,
-     that the storage ultimately comes from the same single storage
-     pool.]
-
-     [ARG Issue: We could make it a run-time check for the storage pools
-     being the same object in the pool-specific case, rather than a
-     compile-time check, eliminating the need that they statically
-     denote the same object.]
+   The expected type for a *subpool_handle*_name is
+   System.Subpools.Subpool_Handle, the type used to identify a subpool
+   defined in the language-defined package System.Subpools (see 13.11).
 
 Modify 4.8(10.1/3) as follows:
 
    ... a check is made that the accessibility level of the anonymous
    access type of each access discriminant is not deeper than that of
    the type of the allocator.   {If a subpool_specification is provided,
-   a check is made that the accessibility level of the specified storage
-   pool object is not deeper than that of the type of the allocator.}
-   Program_Error is raised if [either such check fails] {any of these
-   checks fail}.
+   a check is made that storage pool of the type of the allocator is the
+   subpool manager of the identified subpool.} Program_Error is raised
+   if [either such check fails] {any of these checks fail}.
 
 Modify 13.11(16/3):
 
    An allocator of type T {without a subpool_specification} allocates
-   storage from T's storage pool.  {An allocator with a
-   subpool_specification allocates storage from the specified storage
-   pool.} If the storage pool is a user-defined object, then the storage
-   is allocated by calling Allocate as described below.
-
-     [AARM Note: A subpool_specification might specify T2'Storage_Pool,
-     which might not be a user-defined object, so the condition on the
-     last sentence is relevant even when there is a
-     subpool_specification.]
-
-     [ARG Issue: This does presume we define the accessibility level of
-     T2'Storage_Pool when not user-defined to be the same as that of T2.
-     This implies an update to 3.10.2, I believe.]
+   storage from T's storage pool. If the storage pool is a user-defined object, then
+   the storage is allocated by calling Allocate as described below.
+   {An allocator with a subpool_specification allocates storage from
+   the specified subpool of T's storage pool, by calling Allocate_From_Subpool
+   as described in subclause 13.11.4.}
 
 Add a new section:
 
@@ -242,30 +205,85 @@
 be used for allocation from the associated storage pool, or a particular
 subpool may be specified as part of an allocator (see 4.8).
 
-In Annex H, additional capabilities are defined for managing the
-automatic relamation of subpools (see H.7).
-
 The following language-defined library package exists:
+
+   with System.Storage_Pools;
+   with System.Storage_Elements;
+   package System.Subpools is
+
+       type Root_Subpool_Manager is
+         abstract new Storage_Pools.Root_Storage_Pool with private;
+           -- An access type must have a storage pool of a type
+           -- descended from this type to use subpools.
+
+       type Subpool_Handle(<>) is limited private;
+         -- This is a reference-counted handle on an underlying
+         -- subpool descriptor (see Subpools.Implementation)
+
+       function Create_Subpool(Manager : access Root_Subpool_Manager;
+         Storage_Size : Storage_Elements.Storage_Count :=
+           Storage_Elements.Storage_Count'Last) return Subpool_Handle is abstract;
+           -- Create subpool within given subpool manager.  Storage_Size
+           -- specifies a limit on the amount of storage for the subpool.
+           -- NOTE: Additional functions that create subpools may be
+           --       defined for a given Subpool manager type.
+
+       function Subpool_Manager(Subpool : Subpool_Handle)
+         return access Root_Subpool_Manager'Class;
+         -- Return access to underlying subpool manager of given handle.
+
+       procedure Allocate_From_Subpool(
+         Manager : in out Root_Subpool_Manager;
+         Storage_Address : out Address;
+         Size_In_Storage_Elements : in Storage_Elements.Storage_Count;
+         Alignment : in Storage_Elements.Storage_Count;
+         Subpool : Subpool_Handle) is abstract
+           with Pre'Class => Subpool_Manager(Subpool) = Manager'Access;
+           -- Allocate space from specified subpool.
+
+       function Enclosing_Subpool(Manager : access Root_Subpool_Manager;
+         Storage_Address : Address) return Subpool_Handle is abstract;
+         -- Return the subpool associated with the given address
+         -- NOTE: The implementation of a subpool manager must keep
+         --       track of the subpool from which an object was allocated.
+
+       procedure Allow_Reference(From : Subpool_Handle; To : Subpool_Handle)
+         with Pre => Manager(From) = Manager(To);
+           -- Allow pointers in "From" subpool to safely designate objects
+           -- in "To" subpool, by ensuring that the "To" subpool is not
+           -- reclaimed prior to reclaiming the "From" subpool.
+
+       function Is_Reachable(From : Subpool_Handle; To : Subpool_Handle) return Boolean
+         with Post => (if Manager(From) /= Manager(To) then Is_Reachable'Result = False);
+           -- Return True if "To" subpool is reachable from "From" subpool
+
+       type Default_Subpool_Specifier(<>) is limited private;
+         -- Type used to keep track of the default subpool for a given task.
+       function Establish_Default_Subpool(Subpool : Subpool_Handle)
+         return Default_Subpool_Specifier;
+           -- Set the default subpool for the current task within the
+           -- given subpool's manager.
+       function Default_Subpool(Manager : access Root_Subpool_Manager'Class)
+         return Subpool_Handle;
+           -- Return the default subpool for the current task within the
+           -- given subpool manager.  If no default subpool has been established,
+           -- then this returns a subpool handle which identifies the
+           -- manager's "initial" subpool.  Calls on Allocate for a subpool
+           -- manager will allocate from the default subpool for the
+           -- calling task.
+
+       function Initial_Subpool(Manager : access Root_Subpool_Manager'Class)
+         return Subpool_Handle;
+           -- Return a handle on the "initial" subpool of the given subpool
+           -- manager.  The initial subpool is used when no other subpool has
+           -- been established for a given task.  The initial subpool is not
+           -- reclaimed until the enclosing subpool manager is reclaimed.
+
+       function Is_Initial_Subpool(Subpool : Subpool_Handle) return Boolean;
+         -- Indicates whether the given subpool is the initial subpool for
+         -- its subpool manager.
 
-  with Ada.Finalization;
-  with System.Storage_Elements;
-  with System.Storage_Pools;
-  package System.Subpools is
-
-    type Root_Subpool_Manager is
-      abstract new Storage_Pools.Root_Storage_Pool with private;
-
-    type Root_Subpool(Manager : not null access Root_Subpool_Manager'Class) is
-      abstract new Storage_Pools.Root_Storage_Pool with private;
-
-    type Establish_Default_Subpool(Subpool : not null access Root_Subpool'Class) is
-      new Ada.Finalization.Limited_Controlled with private;
-
-    function Default_Subpool(Subpool_Manager : not null access Root_Subpool_Manager'Class)
-      return access Root_Subpool'Class;
-      -- This returns an access value designating the default subpool associated with a
-      -- given subpool manager, for the current task. It returns null
-      -- if the default subpool is null.
+   end System.Subpools;
 
   private
     ... -- not specified by the language
@@ -275,19 +293,22 @@
 A *subpool* is a storage pool whose type is descended from Root_Subpool.
 The Manager discriminant of a subpool designates its *subpool manager*,
 which is a storage pool whose type is descended from
-Root_Subpool_Manager.
+Root_Subpool_Manager. When an allocator with a subpool_specification
+is evaluated, a call is made on Allocate_From_Subpool passing in the
+given Subpool_Handle, in addition to the parameters as defined
+for calls on Allocate (see 13.11).
+
+When a task creates an object of the type Default_Subpool_Specifier by
+calling Establish_Default_Subpool, the specified Subpool becomes the
+*default subpool* for the subpool's manager, for the given task. When an
+allocator without a subpool_specification is evaluated and the storage
+pool is a subpool manager, the default subpool for that task is used.
+If no default has been established for a given task, the *initial*
+subpool of the subpool manager is used. Finalizing an object of type
+Defaut_Subpool_Specifier restores the default subpool for the given task
+and subpool manager to its state immediately prior to the creation of
+the object.
 
-When a task elaborates the declaration of an object of the type
-Establish_Default_Subpool, the subpool designated by the Subpool
-discriminant becomes the *default subpool* for the subpool's manager,
-for the given task. When an allocator is evaluated and the storage pool
-is a subpool manager, if the task evaluating the allocator has a
-non-null default subpool for that manager, the allocator allocates space
-for the object from that default subpool rather than directly from the
-subpool manager.  Finalizing an object of type Establish_Default_Subpool
-restores the default subpool for the given task and subpool manager to
-its state immediately prior to the elaboration of the object.
-
 [Bounded Error: creating an object of type Establish_Default_Subpool
 with an allocator.]
 
@@ -297,167 +318,99 @@
 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 any parts
-that are task objects) is the master for the subpool, rather than that
-of the access type's collection.  When the subpool object is about to be
-finalized, a check is made whether any of the objects allocated from the
-subpool contain tasks that are not yet terminable.  Program_Error is
-raised if any such tasks exist.  If not, the finalization of the subpool
-proceeds by completing any tasks that are waiting at an open terminate
-alternative, waiting for their termination, and then finalizing all of
-the objects allocated from the subpool.  Finally, any other finalization
-associated with the subpool object itself is performed.
-
-Add the following section:
-
-H.7 Storage Subpool Reclamation
-
-The following language-defined package exists:
-
-  package System.Subpools.Handles is
+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 *ready to be
+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 all of the objects allocated from the subpool.  After a
+subpool has been finalized, any storage allocated for objects in the
+subpool can be reclaimed.
 
-    type Subpool_Handle(Subpool : access Root_Subpool'Class) is
-      new Ada.Finalization.Limited_Controlled with private;
-        -- This represents a (reference-counted) "static" handle on a subpool
-        -- Such a handle is immutable, and continues to designate the same
-        -- subpool as long as it exists.  The handle is "null"
-        -- if the Subpool discriminant is null.
-
-    function Subpool(Subpool_Manager : not null access Root_Subpool_Manager;
-      Addr : System.Address) return Subpool_Handle is abstract;
-      -- This returns a handle on the subpool containing the object
-      -- at the given address. The result is unspecified if the
-      -- address does not designate an object allocated using
-      -- the given subpool manager. The result is null if Addr is Null_Address
-      -- or the object was allocated directly from the subpool manager.
-
-    procedure Allow_Reference(From, To : not null access Root_Subpool'Class);
-      -- This creates a (reference-counted) "dynamic" handle from the
-      -- subpool designated by From to the subpool designated by To. The
-      -- handle is immutable and continues to connect the two subpools as
-      -- long as the "From" subpool exists. After this call, the To
-      -- subpool is "reachable" from the From subpool. The
-      -- "reachable from" relation is transitive, hence, any subpool
-      -- reachable from the To subpool becomes reachable from
-      -- the From subpool.
-
-    function Is_reachable_From(To, From : not null access Root_Subpool'Class) return Boolean;
-      -- This returns True if the "To" subpool is "reachable" from the
-      -- From subpool.
+13.11.5 Subpool Reclamation
 
-  end System.Subpools.Handles;
-
-
 The following language-defined generic package exists:
-
-    generic
-        type Designated_Type(<>) is limited private;
-
-        type Access_Type is access Designated_Type;
-          -- This access type requires a storage pool that supports subpools
 
-    package System.Subpools.References is
-        -- This generic package provides strong and weak references
-        -- to objects allocated from subpools.
-
-        pragma Assert(Access_Type'Storage_Pool in Root_Subpool_Manager'Class);
-          -- This assertion ensures that the access type is associated with
-          -- a storage pool that is a subpool manager.
-
-        function Subpool(Ref : Access_Type) return Subpool_Handle;
-          -- This returns a handle on the subpool containing the object
-          -- designated by Ref. This is implemented by calling the
-          -- Subpool primitive subprogram on the associated storage pool.
-
-        type Object_Reference(Ref : Access_Type) is limited record
-          -- This is a visible record representing the pairing of
-          -- a (static) handle on a subpool with an access value
-          -- protected by the handle.
-            Handle : Subpool_Handle := Subpool(Ref);
-        end record;
-
-        type Strong_Reference is
-          new Ada.Finalization.Controlled with private;
-          -- This private type represents the pairing of a
-          -- reference-counted handle on a subpool and an access
-          -- value protected by the handle. Note that
-          -- strong references are *mutable*. The default value
-          -- of a strong reference is null.
-
-        function Is_Null(Reference : Strong_Reference) return Boolean;
-          -- This returns True if the strong reference does not designate an
-          -- object.
-
-        Null_Strong_Reference : constant Strong_Reference;
-          -- A null-valued reference
-
-        function Create_Strong_Reference(Reference : Object_Reference)
-          return Strong_Reference;
-            -- This creates a strong reference given the
-            -- handle and access value on the designated object.
-
-        function Use_Strong_Reference(Reference : Strong_Reference)
-          return Object_Reference;
-            -- This splits a strong reference into a handle
-            -- on the subpool and an access value on the referenced object.
-
-        type Weak_Reference is
-          new Ada.Finalization.Controlled with private;
-            -- This private type represents the pairing of a
-            -- handle on a subpool and a nullable access value
-            -- designating an object in the subpool. If the
-            -- specified subpool is reclaimed, the access value
-            -- is automatically set to null. A subpool with
-            -- one or more existing weak references will not be reclaimed
-            -- until the enclosing storage pool is exhausted.
-
-        function Is_Null(Reference : Weak_Reference) return Boolean;
-          -- This returns True if the weak reference does not designate an
-          -- object.
-
-        Null_Weak_Reference : constant Weak_Reference;
-          -- A null-valued reference
-
-        function Create_Weak_Reference(Reference : Object_Reference)
-          return Weak_Reference;
-            -- This creates a weak reference given the handle
-            -- and an access value designating the referenced object.
-
-        function Use_Weak_Reference(Reference : Weak_Reference)
-          return Object_Reference;
-            -- This splits a weak reference into a handle on the
-            -- subpool and an access value on the referenced object.
-
-    private
-        ... -- not specified by the language
-
-    end System.Subpools.References;
-
-If an object of type Subpool_Handle is part of an object elaborated
-within a (construct) master, the subpool designated by the Subpool
-discriminant is *reachable from* that master. A subpool is *reachable
-from* a  master for a subpool if it is reachable from the associated
-subpool, as a result of calls on Allow_Reference. A subpool is
-*reachable from* a strong or weak reference if the subpool is reachable
-from the subpool designated by the reference. A subpool is *reachable
-from* itself.
+   with Ada.References;
+   generic
+       type Desig(<>) is limited private;
+       type Acc is access Desig;
+   package System.Subpools.References is
+       -- This generic package provides strong and weak references
+       -- to objects in subpools, which can safely be assigned and
+       -- reassigned without requiring any reachability checks.
+
+       pragma Assert(Acc'Storage_Pool in Root_Subpool_Manager'Class);
+         -- This package is only defined for access types whose storage
+         -- pool is of a type descended from Root_Subpool_Manager.
+
+       function Enclosing_Subpool(Object : not null Desig) return Subpool_Handle;
+         -- Return subpool from which object designated by Object was
+         -- allocated.
+         -- NOTE: This calls the Enclosing_Subpool function in System.Subpools.
+
+       type Strong_Reference is private;
+         -- A strong (reference-counted) reference to an object
+         -- allocated from a subpool.  A strong reference keeps
+         -- the associated subpool from being reclaimed.
+       Null_Strong_Reference : constant Strong_Reference;
+
+       function New_Strong_Reference(Object : Desig) return Strong_Reference;
+           -- Create a strong reference to the given object which
+           -- will prevent premature reclamation of its enclosing subpool.
+
+
+       function Is_Null(Ref : Strong_Reference) return Boolean;
+         -- Return True if pointer within Strong_Reference is null.
+
+       type Object_Ref(Object : not null access Desig) is
+         new Ada.References.Reference with limited private;
+           -- This uses the "magic" interface to provide
+           -- implicit dereference of the result.
+           -- NOTE: This includes a counted reference to
+           --       the subpool to prevent premature
+           --       reclamation while this reference exists.
+
+       function Dereference(Ref : Strong_Reference) return Object_Ref
+         with Pre => not Is_Null(Ref);
+         -- Return a reference to the object identified by the
+         -- Strong_Reference.
+
+       type Weak_Reference is private;
+         -- A weak reference to an object allocated from a subpool.  The
+         -- reference is "weak" in that the associated subpool might be reclaimed
+         -- if the storage is needed.  This is determined by converting
+         -- the weak reference to a strong reference, and then
+         -- checking whether it is null.
+       function New_Weak_Reference(Object : Desig) return Weak_Reference;
+           -- Create a weak reference to an object allocated
+           -- from a subpool.
+
+       function To_Strong_Reference(Ref : Weak_Reference) return Strong_Reference;
+         -- To use a weak reference, it must first be converted
+         -- into a strong reference.
+
+   end System.Subpools.References;
+
+Subpools are automatically finalized and reclaimed when it is safe to do so.
+Subpool handles (see 13.11.4), as well as the *strong references* and *weak
+references* defined in the above generic package, are used to prevent premature
+reclamation, based on a *reachability* relationship. If an object of type
+Subpool_Handle is part of an object elaborated within a (construct) master, the
+subpool identified by the handle is *reachable from* that master. A subpool is
+*reachable from* a master for a subpool if it is reachable from the associated
+subpool, as a result of calls on Allow_Reference. A subpool is *reachable from*
+a strong or weak reference if the subpool is reachable from the subpool
+associated with the reference. A subpool is *reachable from* itself.
 
 [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
+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.]
 
-In an assignment operation, for each part of the assigned value that is
-of an access-to-object type with a storage pool that is a subpool
-manager, a reachability check is performed. This checks that the subpool
-of the object designated by the given part of the assigned value is
-reachable from the master of the target object. If there are multiple
-subcomponents of the assigned value having such an access type, it is
-not specified the order in which these checks are performed. If any of
-these checks fail, Program_Error is raised.
-
 If a subpool is not reachable from any construct master, any strong
 references, nor any master for a subpool with one or more nonterminable
 tasks that depend on it, the given subpool is *ready to be finalized.*
@@ -468,9 +421,120 @@
 its subpools, the allocation procedure may finalize the weakly
 referenced subpool so as to reclaim storage prior to the new allocation.
 
+13.11.6 Subpool Reachability Checks
+
+In an assignment operation, if the target is a variable of an access type whose
+storage pool is a subpool manager, and the value being assigned is non-null,
+then a check is made that the object designed by the value being assigned was
+allocated from a subpool that is reachable from the master of the target object.
+An attribute is provided to check reachability before performing an assignment:
+
+For any variable X and value V of a named access type A:
 
+   X'Reachable(V)
+        Returns True if V is null, or if A'Storage_Pool not in
+        Root_Subpool_Manager'Class; otherwise returns True if and only
+        if Enclosing_Subpool(V) is reachable from the master of X.
+
+Program_Error is raised if this attribute function returns False
+when assigning V to X.  In an assignment of a composite object
+with two or more subcomponents that are of an access type whose
+storage pool is a subpool manager, it is not specified in which
+order these checks are performed.
+
+On conversion to an access type whose storage pool is a subpool manager,
+a check is made that the type of the operand is a named access type
+that has the same storage pool.  Program_Error is raised if this check fails.
+
+
+13.11.7 Subpool Implementation
+
+The following language-defined package exists:
+
+   package System.Subpools.Implementation is
+       -- This package is used by implementations of subpool managers.
+
+       -- The sequence of events is that a call on Create_Subpool goes
+       -- to the subpool manager, it allocates a subpool descriptor,
+       -- then calls New_Subpool_Handle to create a handle.
+
+       -- When a subpool is ready to be reclaimed, the underlying implementation
+       -- waits for any tasks, finalizes the objects in the subpool, then
+       -- calls Reclaim_Subpool_Storage.  Finally, it calls Deallocate
+       -- with the address of the subpool descriptor
+
+       type Root_Subpool_Descriptor(
+          Manager : not null access Root_Subpool_Manager'Class) is
+             abstract tagged limited private;
+         -- This type is used to represent a storage pool within a subpool manager.
+         -- The implementation uses this to represent the dynamic master.  It holds
+         -- the reference count of handles, as well as the count of weak references.
+         -- The subpool manager also uses some extension of this type to keep
+         -- track of the actual storage associated with the subpool so it
+         -- may be reclaimed.
+
+       procedure Reclaim_Subpool_Storage(Subpool : access Root_Subpool_Descriptor)
+         is abstract;
+           -- This is called by the implementation when the subpool is no longer
+           -- reachable from any non-terminable task, and the weak reference
+           -- count is zero, or the Process procedure returns with Reclaim True.
+
+       function New_Subpool_Handle(
+         Subpool : access Root_Subpool_Descriptor'Class) return Subpool_Handle;
+           -- Create a subpool handle given a descriptor of the subpool
+
+       procedure Iterate_Reclaimable_Subpools(Manager : Root_Subpool_Manager'Class;
+         Process : access procedure (Subpool : access Root_Subpool_Descriptor'Class;
+         Weak_Reference_Count : Positive; Reclaim : out Boolean; Quit : out Boolean));
+           -- Iterate through subpools of the given manager which are reclaimable
+           -- because they only have weak references.  This only calls Process for
+           -- one subpool in a given strongly connected set of subpools.
+           -- The Weak_Reference_Count indicates how many weak references identify this
+           -- subpool or some subpool strongly connected to it.  If upon return Reclaim is
+           -- True, then the given subpool and all of its strongly connected
+           -- subpools will be reclaimed.  If Quit is True then the iteration
+           -- will stop.
+
+       procedure Iterate_Connected_Subpools(Subpool : access Root_Subpool_Descriptor'Class;
+         Process : access procedure (Connected_Subpool : access Root_Subpool_Descriptor'Class));
+           -- This iterates through the subpools that are strongly connected to the
+           -- given subpool, meaning that when Subpool is reclaimed, so will be
+           -- all of the connected subpools.  This can be used to determine
+           -- the total amount of storage that will be reclaimed if it is decided
+           -- to reclaim one of the subpools in the strongly-connected set.
+
+   end System.Subpools.Implementation;
+
+Subpools are represented internally by objects of a type
+descended from Root_Subpool_Descriptor, which are allocated
+from the *initial* subpool of the subpool manager. The abstract
+operations on Root_Subpool_Manager and Root_Subpool_Descriptor
+are not provided by the implementation. All other operations
+within System.Subpools, System.Subpools.References, and
+System.Subpools.Implementation, are provided by the
+implementation, for use in implementing overridings of the
+abstract operations.
+
+
 !discussion
 
+There is a delicate "dance" here between code provided by the Ada
+implementation and code provided by the implementor of the subpool
+manager type. The compiler implementation is responsible for worrying
+about reference counting, task dependence, finalization chains,
+reachability checks, weak references. Essentially everything having to
+do with avoiding dangling references. The implementor of the subpool
+manager type is supposed to worry about actually managing the storage
+and keeping track of which storage has been allocated to which subpools.
+The subpool descriptor type can also be extended. So the implementor
+of the subpool manager can keep some information in a per-subpool data
+structure (by extending Root_Subpool_Descriptor), and some globally for
+the overall storage pool (by extending Root_Subpool_Manager).
+
+Meanwhile, the "root part" of these two types will be used by the
+Ada implementation to implement its part of the equation, such as
+finalization, reachability checking, etc.
+
 COMPILE-TIME CHECKING
 
 It is the intent that many of these checks can be performed at
@@ -5104,5 +5168,95 @@
 and that even experienced C++ programmers may not be familiar with it.  So I
 don't buy the "consistency with other languages" argument here, and I think that
 the internal consistency (and readability) of Ada carries more weight.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, February 23, 2010  3:10 AM
+
+Here is another round on subpools. [Editor's Note: This is version /08 of the
+AI.] I have developed this far enough that I believe it can really work. I
+eliminated the Annex H stuff, because Steve convinced me that dumping the
+dangling-reference prevention in there didn't make sense.
+
+I have simplified the chapter 4 part quite a bit.  You will find relatively few
+words there.  I kept the original syntax, because I never saw anything that was
+a substantial improvement, and I don't really buy the argument that somehow the
+type name is more important than the subpool specifier, or vice-versa for that
+matter.  Both are highly relevant.  Having a syntax that will be familiar to C++
+programmers seems a plus, given the importance of interoperability these days.
+
+There are now three library [generic] packages defined in 13.11.*:
+
+    System.Subpools
+    System.Subpools.References
+    System.Subpools.Implementation
+
+The typical user shouldn't have much reason to look in
+System.Subpools.Implementation.  That is meant for the implementor of a subpool
+manager.
+
+I also defined a new attribute:
+
+    X'Reachable(V)
+
+which given a variable X and a value V of an access type A, returns True if the
+subpool containing the object designated by V is "reachable" from the master of
+the object X. That is the basic safety rule.  We always want the subpool
+containing an object designated by a variable to be reachable from that
+variable's master.  If that is true, then we know the subpool will outlive the
+pointer variable, so you won't get a dangling reference.
+
+Subpools are not directly manipulated, in general, but rather they are
+manipulated through "handles."  These handles are reference counted, so that
+when the last handle goes away, the subpool will automatically be reclaimed. In
+a simple case, there is only one handle on a subpool, as a local variable of
+some stack frame, and when you exit that stack frame, the subpool is
+automatically reclaimed.  The reachability checks make sure you don't store
+pointers into that subpool from outside the scope of that stack frame.
+
+One way to think about reachability vs. accessibility, is that accessibility
+checks are essentially involved with preventing inappropriate conversions
+between access *types* with different masters, while reachability checks are
+involved with preventing inappropriate assignments between two pointer *objects*
+with different masters, where both pointers are of the *same* access type.
+
+The packages have been fleshed out further, so as I mentioned above, I believe
+they are actually implementable now.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, February 23, 2010  7:35 AM
+
+Oops.  Type Root_Subpool_Descriptor in package System.Subpools.Implementation
+should be declared as an *abstract* type, since it has an abstract primitive.
+[This correction was made to version /08 - Editor]
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, February 23, 2010  4:35 PM
+
+> Here is another round on subpools.  I have developed this far enough
+> that I believe it can really work.
+
+This offers a lot of assurance, saying as it does that none of the other
+versions could have worked. ;-)
+
+Anyway, you have proposed adding two clauses 13.11.6. I'm pretty sure ISO won't
+allow that. :-)
+
+I've fixed that and the abstract thing from the previous message.
+
+> I eliminated the Annex H stuff, because Steve convinced me that
+> dumping the dangling-reference prevention in there didn't make sense.
+
+Well, I disagree; this version seems to have reintroduced all of the junk that I
+find distasteful. As I've said previously, the one thing that you can't write
+yourself is the early finalization of objects in a subpool. I believe that you
+can write the rest in regular Ada (although you might have to depend on runtime
+checks in some cases). Thus I don't see much reason for it to be in the
+standard, absent demand. We'll discuss this further this weekend.
 
 ****************************************************************

Questions? Ask the ACAA Technical Agent