CVS difference for 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