Contents Index Previous Next
13.11.3 Pragma Controlled
1
[Pragma Controlled is used to prevent any automatic
reclamation of storage (garbage collection) for the objects created by
allocators of a given access type.]
Syntax
2
The form of
a pragma Controlled is as follows:
3
pragma Controlled(
first_subtype_local_name);
3.a
Discussion: Not to be confused
with type Finalization.Controlled.
Legality Rules
4
The first_subtype_local_name
of a pragma Controlled shall denote
a non-derived access subtype.
Static Semantics
5
{representation pragma (Controlled)
[partial]} {pragma, representation
(Controlled) [partial]} A
pragma
Controlled is a representation pragma
{aspect of representation
(controlled) [partial]} {controlled
(aspect of representation)} that specifies
the
controlled aspect of representation.
6
{garbage collection}
Garbage collection is a process that automatically
reclaims storage, or moves objects to a different address, while the
objects still exist.
6.a
Ramification: Storage reclamation
upon leaving a master is not considered garbage collection.
6.b
Note that garbage collection includes
compaction of a pool (``moved to a different Address''), even if storage
reclamation is not done.
6.c
Reason: Programs that will
be damaged by automatic storage reclamation are just as likely to be
damaged by having objects moved to different locations in memory. A pragma
Controlled should turn off both flavors of garbage collection.
6.d
Implementation Note: If garbage
collection reclaims the storage of a controlled object, it should first finalize
it. Finalization is not done when moving an object; any self-relative pointers
will have to be updated by the garbage collector. If an implementation provides
garbage collection for a storage pool containing controlled objects (see 7.6),
then it should provide a means for deferring garbage collection of those controlled
objects.
6.e
Reason:
This allows the manager of a resource released by a Finalize operation
to defer garbage collection during its critical regions; it is up to
the author of the Finalize operation to do so. Garbage collection, at
least in some systems, can happen asynchronously with respect to normal
user code. Note that it is not enough to defer garbage collection during
Initialize, Adjust, and Finalize, because the resource in question might
be used in other situations as well. For example:
6.f
with Ada.Finalization;
package P is
6.g
type My_Controlled is
new Ada.Finalization.Limited_Controlled with private;
procedure Finalize(Object : in out My_Controlled);
type My_Controlled_Access is access My_Controlled;
6.h
procedure Non_Reentrant;
6.i
private
...
end P;
6.j
package body P is
X : Integer := 0;
A : array(Integer range 1..10) of Integer;
6.k
procedure Non_Reentrant is
begin
X := X + 1;
-- If the system decides to do a garbage collection here,
-- then we're in trouble, because it will call Finalize on
-- the collected objects; we essentially have two threads
-- of control erroneously accessing shared variables.
-- The garbage collector behaves like a separate thread
-- of control, even though the user hasn't declared
-- any tasks.
A(X) := ...;
end Non_Reentrant;
6.l
procedure Finalize(Object : in out My_Controlled) is
begin
Non_Reentrant;
end Finalize;
end P;
6.m
with P; use P;
procedure Main is
begin
... new My_Controlled ... -- allocate some objects
... forget the pointers to some of them, so they become garbage
Non_Reentrant;
end Main;
6.n
It is the user's responsibility
to protect against this sort of thing, and the implementation's responsibility
to provide the necessary operations.
6.o
We do not give these operations
names, nor explain their exact semantics, because different implementations
of garbage collection might have different needs, and because garbage
collection is not supported by most Ada implementations, so portability
is not important here. Another reason not to turn off garbage collection
during each entire Finalize operation is that it would create a serial
bottleneck; it might be only part of the Finalize operation that conflicts
with some other resource. It is the intention that the mechanisms provided
be finer-grained than pragma Controlled.
7
If a pragma
Controlled is specified for an access type with a standard storage pool,
then garbage collection is not performed for objects in that pool.
7.a
Ramification: If Controlled
is not specified, the implementation may, but need not, perform garbage
collection. If Storage_Pool is specified, then a pragma
Controlled for that type is ignored.
7.b
Reason: Controlled means
that implementation-provided garbage collection is turned off; if the
Storage_Pool is specified, the pool controls whether garbage collection
is done.
Implementation Permissions
8
An implementation need not support garbage collection,
in which case, a pragma Controlled has no effect.
Wording Changes from Ada 83
8.a
Ada 83 used the term ``automatic storage
reclamation'' to refer to what is known traditionally as ``garbage collection''.
Because of the existence of storage pools (see 13.11),
we need to distinguish this from the storage reclamation that might happen upon
leaving a master. Therefore, we now use the term ``garbage collection'' in its
normal computer-science sense. This has the additional advantage of making our
terminology more accessible to people outside the Ada world.
Contents Index Previous Next Legal