TempAlloc: an unusual request

dsimcha dsimcha at yahoo.com
Sun Jun 19 16:20:08 PDT 2011


On 6/19/2011 12:07 PM, Andrei Alexandrescu wrote:
> On 6/19/11 5:03 AM, Lars T. Kyllingstad wrote:
>> On Sat, 18 Jun 2011 09:00:13 -0500, Andrei Alexandrescu wrote:
>>
>>> I'd like to kindly request the author, the review manager, and the
>>> community that TempAlloc skips this round of reviews without inclusion
>>> in Phobos, to be reviewed again later.
>>
>> As review manager, I don't mind postponing the review until some later
>> time.
>>
>> As a community member and Phobos user, I think it would of course be
>> preferable if TempAlloc fits into a more general allocator interface.
>>
>> As an active TempAlloc user, I hope it doesn't take too long before said
>> interface is decided upon. ;)
>>
>> -Lars
>
> I'm thinking of defining a general interface that catches malloc, the
> GC, scoped allocators a la TempAlloc, and possibly compound allocators a
> la reaps.
>
> I'll start with an example:
>
> struct Mallocator
> {
> /** Allocates a chunk of size s. */
> static void * allocate(size_t s) {
> return enforce(malloc(s), new OutOfMemory);
> }
>
> /** Optional: frees a chunk allocated with allocate */
> static void free(void *p) {
> .free(p);
> }
>
> /** Optional: frees all chunks allocated with allocate */
> // static void freeAll();
>
> /** Resizes a chunk allocated with allocate without moving.
> Required, but may be implemented to always return false. */
> static bool resize(void* p, size_t newSize) {
> // Can't use realloc here
> return false;
> }
>
> /** true if calls to free enforce the pointer is valid */
> enum { freeIsChecked = false }
>
> /** Returns the guaranteed alignment for allocation requests
> of size s. Must be computable during compilation. */
> size_t align(size_t s) { return (void*).sizeof; }
>
> /** Returns the size effectively allocated if an allocation
> of size s were requested. Must be computable during
> compilation.*/
> static size_t allocSize(size_t s) {
> return ((s + align(s) - 1) / align(s)) * align(s);
> }
>
> /** true if memory is automatically reclaimed (GC) */
> enum { isAutomatic = false }
>
> /** true if allocator is scoped, i.e. all memory allocated
> goes away when the original allocator goes out of scope */
> enum { isScoped = false }
> }
>
> This is a symbolic interface. Some or all of the functions above may be
> static. I think, without being yet positive, that the allocator should
> have reference semantics, i.e. all copies of a given allocator should
> manipulate the same memory. This should reduce unwitting errors caused
> e.g. by passing an allocator by reference instead of by value.
>
> For TempAlloc that means the primitives frameInit and frameFree are
> replaced with an object, e.g. RegionAllocator. That object and all of
> its copies manage a given frame. (BTW I think the name "region" is
> consecrated and should replace "frame" throughout in TempAlloc. In fact
> TempAlloc should be renamed to RegionAlloc.)
>

It's ok to allow an object to replace frameInit and frameFree for 
conformance to the general allocator interface, but I'd need to keep 
frameInit and frameFree around.  They're useful for functions that 
return pointers to TempAlloc-allocated memory.  I don't want to have to 
pass in a RegionAllocator object to each of these because it's too 
verbose.  I want to be able to do:

void doStuff() {
    TempAlloc.frameInit();
    scope(exit) TempAlloc.frameFree();

    auto arr = getArray();
}

uint[] getArray() {
    return TempAlloc.newArray!(uint[])(5);
}


My other concern is that giving RegionAllocator reference semantics 
would, IIUC, require an allocation to allocate a RegionAllocator.  Since 
TempAlloc is designed to avoid global GC locks/world stopping like the 
plauge, this is obviously bad.


More information about the Digitalmars-d mailing list