digitalmars.D - Mallocator
- Erik Smith (35/35) Mar 03 2016 Just a question on Mallocator and shared. My code does a lot of
- Brian Schott (3/5) Mar 03 2016 Are you calling `Mallocator.allocate()` or
- Erik Smith (21/26) Mar 03 2016 The later works and qualifying the allocator member variable
- Meta (3/14) Mar 03 2016 Does this still ICE when you write it as `void[] p2 =
- Erik Smith (2/18) Mar 03 2016 No. :)
Just a question on Mallocator and shared. My code does a lot of non-GC heap allocation (malloc) for buffers, so I reached for Mallocator as a starting point. I propagate an Allocator type generically through my structs, but it is defaulted to Mallocator. After checking with the docs & TDPL, I'm still a bit confused on how to deal with the shared functions in Mallocator and what the effect of shared functions is in this context (see code below). I get the error "allocate is not callable using a non-shared object" and I'm not sure how to resolve it. I'm not sure if I should cast shared away (or how to make that work). The docs say malloc/free is thread safe as far as D is concerned, so synchronized doesn't seem to be the answer. Forking Mallocator without shared solved the issue temporarily. Also Allocators are, in general, not copyable so I should propagate them around as references (or pointers in struct members), correct? struct Mallocator{ ... trusted nogc nothrow void[] allocate(size_t bytes) shared { import core.stdc.stdlib : malloc; if (!bytes) return null; auto p = malloc(bytes); return p ? p[0 .. bytes] : null; } system nogc nothrow bool deallocate(void[] b) shared { import core.stdc.stdlib : free; free(b.ptr); return true; } ... }
Mar 03 2016
On Thursday, 3 March 2016 at 19:01:52 UTC, Erik Smith wrote:I get the error "allocate is not callable using a non-shared object" and I'm not sure how to resolve it.Are you calling `Mallocator.allocate()` or `Mallocator.instance.allocate()`?
Mar 03 2016
On Thursday, 3 March 2016 at 19:32:40 UTC, Brian Schott wrote:On Thursday, 3 March 2016 at 19:01:52 UTC, Erik Smith wrote:The later works and qualifying the allocator member variable shared seems to solve the issue. Example: struct A(T) { alias Allocator = T; shared Allocator allocator; this(string url="") { allocator = Allocator(); void *p1 = cast(void*)(allocator.allocate(1024)); //void p2[] = allocator.allocate(1024); // ICE } } A!Mallocator a; However, this seems bad because it assumes that all allocators are shared. It appears, however that the qualifier can be attached to the type so maybe there is some meta-programming tricks that can be used: alias Allocator = shared T; I'm not sure if I'm on the right track. Note also the ICE in the example above. erikI get the error "allocate is not callable using a non-shared object" and I'm not sure how to resolve it.Are you calling `Mallocator.allocate()` or `Mallocator.instance.allocate()`?
Mar 03 2016
On Thursday, 3 March 2016 at 20:16:55 UTC, Erik Smith wrote:The later works and qualifying the allocator member variable shared seems to solve the issue. Example: struct A(T) { alias Allocator = T; shared Allocator allocator; this(string url="") { allocator = Allocator(); void *p1 = cast(void*)(allocator.allocate(1024)); //void p2[] = allocator.allocate(1024); // ICE } }Does this still ICE when you write it as `void[] p2 = allocator.allocate(1024)`?
Mar 03 2016
On Thursday, 3 March 2016 at 20:31:47 UTC, Meta wrote:On Thursday, 3 March 2016 at 20:16:55 UTC, Erik Smith wrote:No. :)The later works and qualifying the allocator member variable shared seems to solve the issue. Example: struct A(T) { alias Allocator = T; shared Allocator allocator; this(string url="") { allocator = Allocator(); void *p1 = cast(void*)(allocator.allocate(1024)); //void p2[] = allocator.allocate(1024); // ICE } }Does this still ICE when you write it as `void[] p2 = allocator.allocate(1024)`?
Mar 03 2016