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

Differences between 1.1 and version 1.2
Log of other versions for file ai05s/ai05-0190-1.txt

--- ai05s/ai05-0190-1.txt	2009/11/04 01:50:30	1.1
+++ ai05s/ai05-0190-1.txt	2009/12/09 01:20:40	1.2
@@ -1,21 +1,35 @@
-!standard D.7(8)                                09-11-03  AI05-0190-1/01
+!standard D.7(8)                                09-11-19  AI05-0190-1/02
 !class amendment 09-11-03
 !status work item 09-11-03
 !status received 09-11-03
 !priority Low
 !difficulty Easy
-!subject Restriction No_Allocation_from_Default_Pools
+!subject Global storage pool controls
 
 !summary
 
-Provide a restriction that disallows use of allocators for types
-that use the default storage pool.
+Provide a means to force the use of user-defined pools, and a means to specify a
+particular pool to be used by default.
 
 !problem
 
-It is common to have a coding convention that only user-defined storage 
-pools be used for all access types.  This restriction allows the 
-implementation to enforce this coding convention.
+Some applications need to keep tight control over heap allocation. For example,
+it is common for object-oriented applications to have many access-to-class-wide
+types, but few used for allocation. Another example is an embedded system for
+which is is inappropriate to rely on the implementation-provided pools.
+
+This can be done by appplying "Storage_Size use 0" to all types that should not
+have allocators, and explicitly specifying a Storage_Pool for the few others.
+But this is error prone; one might forget the "Storage_Size use 0".
+
+Another problem is that it is technically erroneous to deallocate from the
+"wrong" pool. But it is implementation defined which pool is used for each
+access type! Many Ada programmers don't know about this rule, and most Ada
+implementations use a single global heap by default, so it is common to write
+code that does "new" for one type, converts to another type, and does
+Unchecked_Deallocation. This common coding practise could be erroneous on some
+implementations. It is uncomfortable for erroneousness to be implementation
+defined in this way.
 
 !proposal
 
@@ -23,35 +37,298 @@
 
 !wording
 
-Add after D.7(8):
+                                   Syntax
 
-  No_Allocation_From_Default_Pools
-  
-     Every allocator shall be:
-     
-       * of a named access type with a Storage_Pool attribute that
-         denotes a user-defined object;
+The form of a pragma No_Default_Storage_Pool or Default_Storage_Pool is as
+follows:
 
-       * of an anonymous access type, used to define the value of an
-         access parameter or access discriminant; or
+    pragma No_Default_Storage_Pool;
+    pragma Default_Storage_Pool(*storage_pool*_name);
 
-       * of an anonymous access type, used in a context where the storage
-         pool is defined to be the same as that of a permitted allocator.
+A pragma No_Default_Storage_Pool is a configuration pragma.
+A pragma Default_Storage_Pool is allowed at the place where a declarative_item
+is allowed.
 
+
+                            Name Resolution Rules
+
+The *storage_pool*_name is expected to be of type Root_Storage_Pool'Class.
+
+
+                                Legality Rules
+
+The *storage_pool*_name shall denote a variable.
+
+A Default_Storage_Pool shall not be within the immediate scope of another
+Default_Storage_Pool.  [???Or should the inner/later one override the other?
+Sounds complicated, wording-wise and implementation-wise.]
+
+                              Static Semantics
+
+Within the immediate scope of a pragma Default_Storage_Pool, the Storage_Pool
+attribute of any access type to which no Storage_Pool nor Storage_Size clause
+applies is defined to be the pool denoted by the *storage_pool*_name.
+
+If No_Default_Storage_Pool applies to a given compilation_unit, then any access
+type within that compilation_unit that has neither a specified Storage_Pool nor
+Storage_Size is defined by the language to have a Storage_Size of zero.
+[Therefore, an allocator for such a type is illegal.]
+
+    AARM: This implies that Default_Storage_Pool trumps
+    No_Default_Storage_Pool.
+
 !discussion
+
+Expected usage scenarios are:
+
+    - No_Default_Storage_Pool as a configuration pragma applying to the whole
+      program.
+
+      To use an allocator for an access type, you have to apply a Storage_Pool
+      or Storage_Size pragma to that type, or else put a Default_Storage_Pool
+      pragma such that the type is within the pragma's immediate scope.
+
+    - Default_Storage_Pool in the spec of the root package of a program or
+      subsystem.
 
-We have allowed anonymous allocators so long as they can be allocated on
-the stack, or in a storage pool that is user-defined.  We have not
-permitted an allocator for an access type with a Storage_Size attribute,
-because those still involve heap allocation and potentially unchecked
-deallocation using implementation-specific algorithms.
+      This default pool is used within the package and its children,
+      but you can override it with a Storage_Pool or Storage_Size clause.
 
 !example
 
 !ACATS test
 
-An ACATS B test is needed.
+ACATS B and C tests are needed.
 
 !appendix
+
+From: Bob Duff
+Sent: Thursday, November 19, 2009  12:52 PM
+
+New version of AI05-0190-1. [This is version /02 of this AI. - ED]
+
+The previous version used a Restriction to specify "no allocators allowed by
+default".  I added pragma Default_Storage_Pool to specify a pool to be used by
+default.  Having done that, it seemed better to use a pragma
+No_Default_Storage_Pool instead of that Restriction.
+
+I changed the !subject accordingly.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Sunday, November 22, 2009  1:16 PM
+
+I wrote:
+
+> Provide a means to force the use of user-defined pools, and a means to
+> specify a particular pool to be used by default.
+
+One interesting question, which comes from a private conversation I had with
+Laurent Guerby, is:
+
+What happens if pragma Default_Storage_Spool applies to an instantiation?
+Does it apply to access types in the instance?
+If so, does that provide a way to control the storage pool used for instances of
+Ada.Constainers.Vectors and friends?
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, November 24, 2009  12:28 AM
+
+It's clear that No_Default_Storage_Pool had better apply to instances, so that
+any allocators in the generic units are detected. So I suppose from that it
+implies that a similar capability exists in the other direction.
+
+But such a capability would be next to useless. There is not (and better not be,
+IMHO) any requirements on how the containers packages use the (default) storage
+pool (except of course for the bounded forms, where using a pool at all is
+disallowed). In particular, a container can request storage from the pool with
+any size and any alignment, and as part of any operation. I suppose a program
+tied to a particular implementation of the containers might be able to gain some
+advantage from a custom pool, but such code is unlikely to be portable.
+
+Note that this is true of any generic that allocates from the default pool.
+Unless you are willing to "break privacy" by looking into the body of the
+generic, you can't assume anything about how the pool will be called.
+
+But almost all interesting user-defined storage pools make some assumptions
+about the alignment and size that will be requested. Such pools would not work
+on instances. It would of course be possible to create a monitoring pool that
+passes the actual allocation requests to the default pool, but that is not going
+to be very helpful in managing storage use.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, November 24, 2009  12:52 AM
+
+> !wording
+
+Minor issue - you didn't recommend some place to put this new wording. It can't
+be floating in space!!
+
+The old positioning of D.7(8) related specifically to it being a restriction, so
+that doesn't work. So some other suggestion is needed.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Tuesday, November 24, 2009   7:01 AM
+
+Right.  I intended to suggest someplace in chap 13, but I forgot.
+So I'd say it should be 13-dot-<rolldice>.
+
+I'm presuming there was no deliberate intent to max this "optional annex" --
+it's just where the Restrictions happen to live.
+
+Actually, I guess it should be 13.11.3, "Default Storage Pools", and bump
+"Pragma Controlled" up to 13.11.4.
+
+What about the proposal overall?  Do people like it?
+It's radically different from the previous version.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, November 24, 2009   7:36 AM
+
+> But such a capability would be next to useless.
+
+I don't agree this would be next to useless for a container instance.  Clearly
+you would have to provide a general purpose storage pool if you are going to
+apply it by default to your entire system.  But often all that is wanted is an
+ability to replace the system-defined default storage pool with a
+project-specific default storage pool.
+
+Unlike your experience, most of the storage pools I create are general purpose
+in the sense that they handle any size or alignment, but are more specific in
+when/if any automatic reclamation occurs.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, November 24, 2009  5:45 PM
+
+> I don't agree this would be next to useless for a container instance.
+> Clearly you would have to provide a general purpose storage pool if
+> you are going to apply it by default to your entire system.  But often
+> all that is wanted is an ability to replace the system-defined default
+> storage pool with a project-specific default storage pool.
+
+Not sure that makes much sense (unless your vendor's pool is particularly bad,
+or if you need additional monitoring capabilities).
+
+> Unlike your experience, most of the storage pools I create are general
+> purpose in the sense that they handle any size or alignment, but are
+> more specific in when/if any automatic reclamation occurs.
+
+Fine, but those aren't very necessary with the containers, which already are
+handling storage management (they're required not to leak, after all). So you
+are essentially repeating the existing storage management. Moreover, the
+containers (other than the bounded ones) are using controlled objects, and
+freeing storage in that case makes your program erroneous (and might very well
+cause it to crash hard, depending on how controlled objects are implemented).
+The only time it is safe to free storage is if the instance has gone away, and
+in that case, the "no leak" rule means that the storage has already been freed.
+So while I could see that this capability might be useful with your own
+generics, it wouldn't have any real value with the unbounded/indefinite
+containers.
+
+One could imagine trying to constrain implementation choices for the unbounded
+containers so that pools could be useful (for instance, we'd have to ban reusing
+nodes in a different object after they're deleted -- a technique I was planning
+to use). But that comes uncomfortably close to requiring the containers to have
+a particular body, something that was previously rejected.
+
+Anyway, I still think this capability would necessarily have to be provided in
+Bob's proposal (it doesn't make sense otherwise), but I don't think it should be
+suggested that it has any particular utility for the language-defined packages.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, November 24, 2009   7:39 AM
+
+I don't understand why No_Default_Storage_Pool is made into its own pragma,
+rather than relying on a restriction.  All you said was:
+
+   ... it seemed better to use a pragma
+   No_Default_Storage_Pool instead of that Restriction.
+
+Could you provide a bit more rationale?  It smells and feels like a restriction,
+so I don't see the advantage of not using the Restrictions pragma.
+
+I also find the wording for No_Default_Storage_Pool a bit confusing, as it says
+that an access type that
+
+    ... has neither a specified Storage_Pool nor Storage_Size ...
+
+ends up with Storage_Size 0.  But it isn't clear from the pragma
+Default_Storage_Pool that this has the effect of giving an access type a
+*specified* Storage_Pool. I think from a language point of view it is still
+unspecified, but it picks up the Default_Storage_Pool precisely because it is
+unspecified.  Hence I would recommend that you be more explicit and say that any
+access type that is "not within the scope of a Default_Storage_Pool nor has a
+specified Storage_Pool nor a specified Storage_Size..." ends up with a
+Storage_Size of zero.
+
+It is somewhat annoying that Default_Storage_Pool can't be a configuration
+pragma, but I understand the problem.  It would be nice if you could just
+specify it once and have it apply "everywhere." I suppose if you organize your
+library units into a small number of large subsystems, then you would only need
+one per top-level library package. For example, in the RTS you would only need
+it in the specs for Ada, Interfaces, and System. Of course creating a storage
+pool object that can live in a Pure package would be a bit of a challenge!
+Especially if it has to depend on System.Storage_Pools... ;-)
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, November 24, 2009  5:50 PM
+
+> I don't understand why No_Default_Storage_Pool is made into its own
+> pragma, rather than relying on a restriction.
+
+Bob might have a better reason, but to me it seems that
+"No_Default_Storage_Pool" is just another form of specifying the default storage
+pool. Perhaps it would be better to just use one pragma:
+
+     pragma Default_Storage_Pool (null);
+
+to mean no default pool, although that would require rather annoying resolution
+and legality rules.
+
+In that sense it isn't really a restriction, it is just the absence of a default
+storage pool. (Every access type must have a pool before an allocator can be
+used - Storage_Size = 0 could be thought of as the same as not having a pool. I
+assume Bob worded it to the other way to minimize the wording changes needed.)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, November 24, 2009  7:17 PM
+
+I don't think this accomplishes what Bob (and I want).
+You want this to be a configuration pragma, and probably be one of those that
+you give all by itself in a file, so it applies to the whole library. That's why
+I think it makes the most sense as a restriction.
+
+And yes, this is for cases where you want to monitor and/or control *all*
+allocation, because you don't trust or you haven't certified the vendor-provided
+default storage pool, or you simply have special requirements relating to
+storage management in the given target environment.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, November 25, 2009  12:38 PM
+
+I was assuming that this would be a configuration pragma. I'm not sure why you
+assumed otherwise. Of course, you couldn't give an actual pool in that case
+because none would be visible. But there would be no problem with giving "null"
+in that usage. So only one pragma is needed, and there is no need to worry about
+what happens when they conflict.
 
 ****************************************************************

Questions? Ask the ACAA Technical Agent