www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Problems with std.experimental.allocator

reply Igor <stojkovic.igor gmail.com> writes:
I realize these are not yet stable but I would like to know if I 
am doing something wrong or is it a lib bug.

My first attempt was to do this:

	theAllocator = allocatorObject(Region!MmapAllocator(1024*MB));

If I got it right this doesn't work because it actually does this:

1. Create Region struct and allocate 1024MB from MMapAllocator
2. Wrap the struct in IAllocator by copying it because it has 
state
3. Destroy original struct which frees the memory
4. Now the struct copy points to released memory

Am I right here?

Next attempt was this:

	theAllocator = 
allocatorObject(Region!()(cast(ubyte[])MmapAllocator.instance.allocate(1024*MB)));

Since I give actual memory instead of the allocator to the Region 
it can not dealocate that memory so even the copy will still 
point to valid memory. After looking at what will the 
allocatorObject do in this case my conclusion is that it will 
take a "copyable" static if branch and create an instance of 
CAllocatorImpl which will have a "Region!() impl" field within 
itself but given Region!() struct is never copied into that field.

Am I right here?

If I am right about both are then these considered as lib bugs?

I finally got it working with:

	auto newAlloc = 
Region!()(cast(ubyte[])MmapAllocator.instance.allocate(1024*MB));
	theAllocator = allocatorObject(&newAlloc);

Next I tried setting processAllocator instead of theAllocator by 
using:

     auto newAlloc = 
Region!()(cast(ubyte[])MmapAllocator.instance.allocate(1024*MB));
     processAllocator = sharedAllocatorObject(&newAlloc);

but that complained how it "cannot implicitly convert expression 
`pa` of type `Region!()*` to `shared(Region!()*)`" and since 
Region doesn't define its methods as shared does this mean one 
can not use Region as processAllocator? If that is so, what is 
the reason behind it?
Sep 02 2017
parent Igor <stojkovic.igor gmail.com> writes:
On Saturday, 2 September 2017 at 11:23:00 UTC, Igor wrote:
 I realize these are not yet stable but I would like to know if 
 I am doing something wrong or is it a lib bug.

 My first attempt was to do this:

 	theAllocator = allocatorObject(Region!MmapAllocator(1024*MB));

 If I got it right this doesn't work because it actually does 
 this:

 1. Create Region struct and allocate 1024MB from MMapAllocator
 2. Wrap the struct in IAllocator by copying it because it has 
 state
 3. Destroy original struct which frees the memory
 4. Now the struct copy points to released memory

 Am I right here?

 Next attempt was this:

 	theAllocator = 
 allocatorObject(Region!()(cast(ubyte[])MmapAllocator.instance.allocate(1024*MB)));

 Since I give actual memory instead of the allocator to the 
 Region it can not dealocate that memory so even the copy will 
 still point to valid memory. After looking at what will the 
 allocatorObject do in this case my conclusion is that it will 
 take a "copyable" static if branch and create an instance of 
 CAllocatorImpl which will have a "Region!() impl" field within 
 itself but given Region!() struct is never copied into that 
 field.

 Am I right here?

 If I am right about both are then these considered as lib bugs?

 I finally got it working with:

 	auto newAlloc = 
 Region!()(cast(ubyte[])MmapAllocator.instance.allocate(1024*MB));
 	theAllocator = allocatorObject(&newAlloc);

 Next I tried setting processAllocator instead of theAllocator 
 by using:

     auto newAlloc = 
 Region!()(cast(ubyte[])MmapAllocator.instance.allocate(1024*MB));
     processAllocator = sharedAllocatorObject(&newAlloc);

 but that complained how it "cannot implicitly convert 
 expression `pa` of type `Region!()*` to `shared(Region!()*)`" 
 and since Region doesn't define its methods as shared does this 
 mean one can not use Region as processAllocator? If that is so, 
 what is the reason behind it?
After a lot of reading I learned that I need a separate implementation like SharedRegion and I tried implementing one. If anyone is interested you can take a look here https://github.com/igor84/dngin/blob/master/source/util/allocators.d. It doesn't have expand at the moment but I tried making it work with this: processAllocator = sharedAllocatorObject(shared SharedRegion!MmapAllocator(1024*MB)); I did it by reserving first two bytes of allocated memory for counting the references to that memory and then increasing that count on postblit and decreasing it in destructor and identity assignment operator. I then only release the memory if this count gets bellow 0. Problem is I couldn't get it to compile since I would get this error on above line: Error: shared method util.allocators.SharedRegion!(MmapAllocator, 8u, cast(Flag)false).SharedRegion.~this is not callable using a non-shared object I couldn't figure out why is it looking for non-shared destructor. If I remove shared from destructor then I get that "non-shared method SharedRegion.~this is not callable using a shared object" in std/experimental/allocator/package.d(2067). I currently use it with pointer construction: https://github.com/igor84/dngin/blob/master/source/winmain.d#L175
Sep 03 2017