Jump to page: 1 2
Thread overview
D's New GC and Object Allocation Pools
Oct 26, 2014
Mike
Oct 26, 2014
Mike
Oct 26, 2014
Mike
Oct 26, 2014
Iain Buclaw
Oct 26, 2014
Mike
Oct 27, 2014
Mike
Oct 26, 2014
Kyoji Klyden
Oct 26, 2014
Damian
Oct 26, 2014
Kagamin
Oct 26, 2014
Sean Kelly
Oct 26, 2014
Kagamin
October 26, 2014
Hello,

I was wondering if there have been updates regarding Andrei's announcement that he would rewrite the D garbage collector. Is there any kind of timeline for when a new version of the GC can be expected?

I also wanted to ask if there was an implementation of an object pool in the standard library. If not, I'm wondering what the best way to implement this is. Is there any way to overload new and destroy?

I was thinking of using the templated emplace operator from std.conv to allocate class objects into a large flat array, and to derive pool-allocated classes from a PoolObject base class. This base class would contain linked list pointers to implement a free list, as well as templated static methods to allocate and free the objects. Any advice welcome.
October 26, 2014
On Sunday, 26 October 2014 at 03:37:47 UTC, Maxime Chevalier-Boisvert wrote:
>
> I also wanted to ask if there was an implementation of an object pool in the standard library. If not, I'm wondering what the best way to implement this is. Is there any way to overload new and destroy?

I'm not an authority on the subject, but I believe all you need to do is provide alternate implementations for _d_newclass[1] and destroy[2].  I experimented with this a little bit about a year ago, and it worked well for me.  I modified druntime for my experiments, but there may be a way to link in your implementations instead of the defaults at link time, thus giving you an "override" effect.

>
> I was thinking of using the templated emplace operator from std.conv to allocate class objects into a large flat array, and to derive pool-allocated classes from a PoolObject base class. This base class would contain linked list pointers to implement a free list, as well as templated static methods to allocate and free the objects. Any advice welcome.

If you haven't already, check out the Memory Management article on the D Wiki [3].  It's a nice article that was written some time ago by an unknown author and migrated to the wiki last year to help keep it maintained.  I particularly like Explicit Class Allocation[4], Mark/Release[5], and Free Lists[6] as alternatives.

Mike

[1] - https://github.com/D-Programming-Language/druntime/blob/master/src/rt/lifetime.d#L60
[2] - https://github.com/D-Programming-Language/druntime/blob/master/src/object_.d#L2379
[3] - http://wiki.dlang.org/Memory_Management
[4] - http://wiki.dlang.org/Memory_Management#Explicit_Class_Instance_Allocation
[5] - http://wiki.dlang.org/Memory_Management#Mark.2FRelease
[6] - http://wiki.dlang.org/Memory_Management#Free_Lists
October 26, 2014
On Sunday, 26 October 2014 at 03:37:47 UTC, Maxime
Chevalier-Boisvert wrote:
> Hello,
>
> I was wondering if there have been updates regarding Andrei's announcement that he would rewrite the D garbage collector. Is there any kind of timeline for when a new version of the GC can be expected?
>
> I also wanted to ask if there was an implementation of an object pool in the standard library. If not, I'm wondering what the best way to implement this is. Is there any way to overload new and destroy?
>
> I was thinking of using the templated emplace operator from std.conv to allocate class objects into a large flat array, and to derive pool-allocated classes from a PoolObject base class. This base class would contain linked list pointers to implement a free list, as well as templated static methods to allocate and free the objects. Any advice welcome.

Regarding the GC, the last I heard Andrei didn't have it at the
top of his to do list. He seems to be putting most of his effort
right now into completing the C++ integration. However, work on
the GC is still in high demand it would seem.

(I don't have any helpful answers for your other questions,
though.. sry!)
October 26, 2014
On Sunday, 26 October 2014 at 04:22:29 UTC, Mike wrote:
> but there may be a way to link in your implementations instead of the defaults at link time, thus giving you an "override" effect.
>

The technique I was thinking of here is the --wrap option in the ld linker [1] (See the bottom of the page).  I use this in my microcontroller programming to override malloc and friends for devices that have discontinuous memory and no MMU.

I tried this on my Linux desktop, and while everything compiled and linked without errors, it resulted in a segmentation fault at runtime.  But where I have failed, others may succeed.  I tested with LDC and GDC, but not DMD.

Mike

[1] http://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.html
October 26, 2014
On Sunday, 26 October 2014 at 07:08:21 UTC, Mike wrote:

> I tried this on my Linux desktop, and while everything compiled and linked without errors, it resulted in a segmentation fault at runtime.  But where I have failed, others may succeed.  I tested with LDC and GDC, but not DMD.

It does work, but for some reason if I replace the printf statement below with D's writeln, I get a segmentation fault.  I don't know why.  Anywhere here's a trivial example to illustrate the idea.

module main;

import std.stdio;
import core.stdc.stdio;

extern (C) Object __wrap__d_newclass(const ClassInfo ci)
{
    printf("You haven't provided any custom allocation yet!\n");
    while(true) {}
    return null;
}

void main(string[] args)
{

}

Compile with:
gdc -Wl,-wrap,_d_newclass main.d

You'll see it output the string before it even reaches main because the runtime initialization seems to allocate a few things.  But, you get the idea. destroy is just a template, however, so it will need a different method.

Mike
October 26, 2014
On 26 Oct 2014 08:05, "Mike via Digitalmars-d" <digitalmars-d@puremagic.com> wrote:
>
> On Sunday, 26 October 2014 at 07:08:21 UTC, Mike wrote:
>
>> I tried this on my Linux desktop, and while everything compiled and
linked without errors, it resulted in a segmentation fault at runtime.  But where I have failed, others may succeed.  I tested with LDC and GDC, but not DMD.
>
>
> It does work, but for some reason if I replace the printf statement below
with D's writeln, I get a segmentation fault.  I don't know why.  Anywhere here's a trivial example to illustrate the idea.
>

The std.stdio module has a shared static this which initialises the File wrapper around C's stdin, stdout, and stderr.  I would first assume that it segv's because the wrapper or internal pointer is null.

Iain.


October 26, 2014
On Sunday, 26 October 2014 at 03:37:47 UTC, Maxime Chevalier-Boisvert wrote:
> Hello,
>
> I was wondering if there have been updates regarding Andrei's announcement that he would rewrite the D garbage collector. Is there any kind of timeline for when a new version of the GC can be expected?
>
> I also wanted to ask if there was an implementation of an object pool in the standard library. If not, I'm wondering what the best way to implement this is. Is there any way to overload new and destroy?
>
> I was thinking of using the templated emplace operator from std.conv to allocate class objects into a large flat array, and to derive pool-allocated classes from a PoolObject base class. This base class would contain linked list pointers to implement a free list, as well as templated static methods to allocate and free the objects. Any advice welcome.

For your object pool, why not just create functions, alloc and free, instead of trying to override them - something like below

version (USE_GC)
{
  import core.memory;
}
else
{
  import core.stdc.stdlib: malloc, free;
}

struct MemPool
{
  void* alloc(size_t size, bool usePool = true) nothrow
  {
    version (USE_GC) return GC.malloc(size);
    else malloc(size);
  }

  void Free(void* p) nothrow
  {
    version (USE_GC) GC.free(p);
    else free(p);
  }
}
October 26, 2014
What I'm trying to do is have some specific classes be pool-allocated though, not completely circumvent the GC.

On Sunday, 26 October 2014 at 08:02:25 UTC, Mike wrote:
> On Sunday, 26 October 2014 at 07:08:21 UTC, Mike wrote:
>
>> I tried this on my Linux desktop, and while everything compiled and linked without errors, it resulted in a segmentation fault at runtime.  But where I have failed, others may succeed.  I tested with LDC and GDC, but not DMD.
>
> It does work, but for some reason if I replace the printf statement below with D's writeln, I get a segmentation fault.  I don't know why.  Anywhere here's a trivial example to illustrate the idea.
>
> module main;
>
> import std.stdio;
> import core.stdc.stdio;
>
> extern (C) Object __wrap__d_newclass(const ClassInfo ci)
> {
>     printf("You haven't provided any custom allocation yet!\n");
>     while(true) {}
>     return null;
> }
>
> void main(string[] args)
> {
>
> }
>
> Compile with:
> gdc -Wl,-wrap,_d_newclass main.d
>
> You'll see it output the string before it even reaches main because the runtime initialization seems to allocate a few things.  But, you get the idea. destroy is just a template, however, so it will need a different method.
>
> Mike

October 26, 2014
I'll do that if I have to, but it's cleaner with an override of new as it makes it impossible to mistakenly allocate the object outside of the pool. It's also nicer if you can pass arguments to your constructor.

On Sunday, 26 October 2014 at 11:16:39 UTC, Damian wrote:
> On Sunday, 26 October 2014 at 03:37:47 UTC, Maxime Chevalier-Boisvert wrote:
>> Hello,
>>
>> I was wondering if there have been updates regarding Andrei's announcement that he would rewrite the D garbage collector. Is there any kind of timeline for when a new version of the GC can be expected?
>>
>> I also wanted to ask if there was an implementation of an object pool in the standard library. If not, I'm wondering what the best way to implement this is. Is there any way to overload new and destroy?
>>
>> I was thinking of using the templated emplace operator from std.conv to allocate class objects into a large flat array, and to derive pool-allocated classes from a PoolObject base class. This base class would contain linked list pointers to implement a free list, as well as templated static methods to allocate and free the objects. Any advice welcome.
>
> For your object pool, why not just create functions, alloc and free, instead of trying to override them - something like below
>
> version (USE_GC)
> {
>   import core.memory;
> }
> else
> {
>   import core.stdc.stdlib: malloc, free;
> }
>
> struct MemPool
> {
>   void* alloc(size_t size, bool usePool = true) nothrow
>   {
>     version (USE_GC) return GC.malloc(size);
>     else malloc(size);
>   }
>
>   void Free(void* p) nothrow
>   {
>     version (USE_GC) GC.free(p);
>     else free(p);
>   }
> }

October 26, 2014
On Sunday, 26 October 2014 at 03:37:47 UTC, Maxime Chevalier-Boisvert wrote:
>
> I also wanted to ask if there was an implementation of an object pool in the standard library. If not, I'm wondering what the best way to implement this is. Is there any way to overload new and destroy?

Andrei has an allocator proposal that seemed largely done but for whatever reason it hasn't been submitted yet.

http://erdani.com/d/phobos-prerelease/std_allocator.html

Object pools seems like the kind of thing it should be good at.
« First   ‹ Prev
1 2