From: Maciej Sobczak on
Hi,

Is it possible to set up a custom allocator for use with any given Ada
container?

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com
From: Dmitry A. Kazakov on
On Mon, 7 Jan 2008 07:48:58 -0800 (PST), Maciej Sobczak wrote:

> Is it possible to set up a custom allocator for use with any given Ada
> container?

Formally yes, the container type is just a type and you can declare a
pool-specific access type for it.

Though, if the container implementation allocates some things privately,
then you have no influence on how it does that, unless this allocation is
exposed in container's interface.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
From: Randy Brukardt on
"Maciej Sobczak" <see.my.homepage(a)gmail.com> wrote in message
news:472f2c87-1238-42a5-8b94-92e9b70981da(a)f47g2000hsd.googlegroups.com...
> Hi,
>
> Is it possible to set up a custom allocator for use with any given Ada
> container?

If you mean an allocator for the private data of the container (which
includes all of the elements and is the bulk of the container), the answer
is no. The standard Ada containers do not provide any mechanism to control
how/were the container allocates memory.

We've discussed whether it would be possible to change that (perhaps by
including a Storage_Pool parameter to the instantiation), but that would be
(a) rather inconvenient, as there is no name for the standard storage pool,
and there was substantial opposition to defining one; (b) very constraining
on implementations, as the allocation behavior of the container would have
to be fairly strongly defined in order for this to be useful (or, the
storage pool passed would have to be completely general, allowing any size
allocation, which would eliminate the vast majority of interesting things
that you can do with storage pools).

Thus, it seems more valuable to have bounded forms for which all of the
allocation can be part of the container object, in which case a regular
access type and allocator would do the trick. There is a project to define
those in the works, but it hasn't been making a lot of progress.

Randy.


From: Maciej Sobczak on
On 8 Sty, 02:54, "Randy Brukardt" <ra...(a)rrsoftware.com> wrote:

> > Is it possible to set up a custom allocator for use with any given Ada
> > container?
>
> If you mean an allocator for the private data of the container (which
> includes all of the elements and is the bulk of the container), the answer
> is no.

This is exactly what I mean. It is not uncommon for a program to have
a majority of its dynamic memory managed by containers.

> The standard Ada containers do not provide any mechanism to control
> how/were the container allocates memory.

This limitation prevents programmers from doing many interesting
optimizations. Even if we put performance issues aside, I might want
to control the memory allocation for reliability.

[...]
> (or, the
> storage pool passed would have to be completely general, allowing any size
> allocation, which would eliminate the vast majority of interesting things
> that you can do with storage pools).

There are ways to overcome this problem, at least for some container
types. Node-based containers could use fixed-size allocators, but of
course it is the container which would then instantiate the allocator
with the proper node size. It was possible in C++.

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com
From: Randy Brukardt on
"Maciej Sobczak" <see.my.homepage(a)gmail.com> wrote in message
news:fb7764c5-31f9-488d-a0e6-53ffd6c96182(a)k39g2000hsf.googlegroups.com...
> On 8 Sty, 02:54, "Randy Brukardt" <ra...(a)rrsoftware.com> wrote:
....
> > The standard Ada containers do not provide any mechanism to control
> > how/were the container allocates memory.
>
> This limitation prevents programmers from doing many interesting
> optimizations. Even if we put performance issues aside, I might want
> to control the memory allocation for reliability.

Yes, of course. It could be used for performance monitoring as well. But I
wouldn't characterize it as "many" interesting optimizations, it's more like
a few interesting things. But it isn't valuable enough to force every user
of a container to define a storage pool (since there is no name for a
standard storage pool). And we needed to keep the number of standard
containers manageable.

> [...]
> > (or, the
> > storage pool passed would have to be completely general, allowing any
size
> > allocation, which would eliminate the vast majority of interesting
things
> > that you can do with storage pools).
>
> There are ways to overcome this problem, at least for some container
> types. Node-based containers could use fixed-size allocators, but of
> course it is the container which would then instantiate the allocator
> with the proper node size. It was possible in C++.

Only if you put severe limits on the implementations. For one thing, you
would need to know the fixed node size in the storage pool in order to take
any realistic advantage of it, but you couldn't ask the container's
implementation for that size since you'd have to pass the storage pool to
the instance. The only practical way to do that is to *require* a particular
node layout. We might as well just standardize the source code of the
container body in that case.

Moreover, there is no requirement in Ada that objects be laid out
continuously. Janus/Ada will often make several allocator calls when
allocating parts of an object, and those calls will all be different sizes.
That's especially true inside of a generic body, where essentially
everything that depends on a formal type is of an unknown size and thus has
to be allocated separately. Even if you had the source code of the body, it
probably would make different calls to Storage_Pool.Allocate on Janus/Ada
and on GNAT.

We'd also have to define what operations can calls the allocators.
Currently, there are no such restrictions on the containers implementation.

Also, of course, it would only work for a couple of the containers. All of
the hashed forms also are going to allocate the hash table, so there are
going to be odd-size allocations (more than just nodes). And the vectors are
likely to allocate chunks of various sizes.

The net effect is that this is not possible to define (or use) in any
useful, portable way. (If you're willing to stick to a single vendor, then
it is more possible, but that of course has nothing to do with the
standard.) Combined with the inability to name the standard storage pool,
there isn't much point in doing this for the primary containers.

The basic idea of the containers was to define a specification, and allow
implementers to innovate on the implementations. (They don't even have to be
in Ada.) The extra specification required to allow passing in a storage pool
would seriously reduce these possibilities.

The bounded forms seem to allow even better control over dynamic allocation
(by not having any in the common case, although that surely wouldn't be true
for Janus/Ada), are much easier to use (don't have to write a storage pool),
and would work for the high-intergrity types that cannot allow an allocator
near their program. Thus, they're the first focus of work. There are a lot
of other ideas, but I can't say what if anything will come of them.

Randy.