Re: std.expreimantal.allocator deallocate

2021-01-25 Thread vitamin via Digitalmars-d-learn

On Monday, 25 January 2021 at 10:28:11 UTC, Jacob Carlborg wrote:

On Sunday, 24 January 2021 at 11:00:17 UTC, vitamin wrote:


void destruct(Base base){
void[] x = (cast(void*)base)[0 .. 
__traits(classInstanceSize, Base)];

writeln("deallocate: ", x.length);
theAllocator.deallocate(x);
}


You can get the dynamic size of an object using 
`typeid(base).initializer.length`.


Base base = new Derived;
assert(__traits(classInstanceSize, Derived) == 
typeid(base).initializer.length);


--
/Jacob Carlborg


I implementing ref counted pointer with support for weak 
pointers. Problem was that expired weak pointer can point to 
already destroyed data => typeid() no longer work or ref type is 
extern(C) class => typeid() doesn't work.


Re: std.expreimantal.allocator deallocate

2021-01-25 Thread Jacob Carlborg via Digitalmars-d-learn

On Sunday, 24 January 2021 at 11:00:17 UTC, vitamin wrote:


void destruct(Base base){
void[] x = (cast(void*)base)[0 .. 
__traits(classInstanceSize, Base)];

writeln("deallocate: ", x.length);
theAllocator.deallocate(x);
}


You can get the dynamic size of an object using 
`typeid(base).initializer.length`.


Base base = new Derived;
assert(__traits(classInstanceSize, Derived) == 
typeid(base).initializer.length);


--
/Jacob Carlborg




Re: std.expreimantal.allocator deallocate

2021-01-25 Thread vitamin via Digitalmars-d-learn
On Sunday, 24 January 2021 at 18:38:42 UTC, Petar Kirov 
[ZombineDev] wrote:

On Sunday, 24 January 2021 at 14:56:25 UTC, Paul Backus wrote:

[...]


To add to that, if an allocator defines 
`resolveInternalPointer` [0][1] you could be able to get the 
original slice that was allocated (and then pass that to 
`deallocate`, but not all allocators define 
`resolveInternalPointer` and also even if they do define it, 
they're not required to maintain complete book-keeping as doing 
so could have bad performance implications (i.e. calling say 
`a.resolveInternalPointer(a.allocate(10)[3 .. 6].ptr, result)` 
can return `Ternary.unknown`.


[0]: 
https://dlang.org/phobos/std_experimental_allocator.html#.IAllocator.resolveInternalPointer
[1]: 
https://dlang.org/phobos/std_experimental_allocator_building_blocks.html


Thanks


Re: std.expreimantal.allocator deallocate

2021-01-24 Thread Petar via Digitalmars-d-learn

On Sunday, 24 January 2021 at 14:56:25 UTC, Paul Backus wrote:

On Sunday, 24 January 2021 at 11:00:17 UTC, vitamin wrote:
It is Ok when I call deallocate with smaller slice or I need 
track exact lengtht?


It depends on the specific allocator, but in general, it is 
only guaranteed to work correctly if the slice you pass to 
deallocate is exactly the same as the one you got from allocate.


To add to that, if an allocator defines `resolveInternalPointer` 
[0][1] you could be able to get the original slice that was 
allocated (and then pass that to `deallocate`, but not all 
allocators define `resolveInternalPointer` and also even if they 
do define it, they're not required to maintain complete 
book-keeping as doing so could have bad performance implications 
(i.e. calling say `a.resolveInternalPointer(a.allocate(10)[3 .. 
6].ptr, result)` can return `Ternary.unknown`.


[0]: 
https://dlang.org/phobos/std_experimental_allocator.html#.IAllocator.resolveInternalPointer
[1]: 
https://dlang.org/phobos/std_experimental_allocator_building_blocks.html


Re: std.expreimantal.allocator deallocate

2021-01-24 Thread Petar via Digitalmars-d-learn

On Sunday, 24 January 2021 at 16:16:12 UTC, vitamin wrote:

On Sunday, 24 January 2021 at 14:56:25 UTC, Paul Backus wrote:

On Sunday, 24 January 2021 at 11:00:17 UTC, vitamin wrote:
It is Ok when I call deallocate with smaller slice or I need 
track exact lengtht?


It depends on the specific allocator, but in general, it is 
only guaranteed to work correctly if the slice you pass to 
deallocate is exactly the same as the one you got from 
allocate.


thanks,
is guaranteed this:

void[] data = Allocator.allocate(data_size);
assert(data.length == data_size)


or can be data.length >= data_size ?


Yes, it is guaranteed [0]. Even though some allocator 
implementations will allocate a larger block internally to back 
your requested allocation size, `allocate` [1] must return the 
same number of bytes as you requested, or a `null` slice.
If an allocator has a non-trivial `goodAllocSize(s)` [2] function 
(i.e. one that is not the identity function `s => s`) and you you 
allocate say N bytes, while allocator.goodAllocSize(N) returns M, 
M > N, it means that most likely calling `expand` [3] will 
succeed - meaning it will give you the excess memory that it has 
internally for free. I say "most likely", because this is the 
intention of the allocator building blocks spec, even though it's 
not specified. In theory, `expand` could fail in such situation 
either because of an allocator implementation deficiency (which 
would technically not be a bug), or because `allocate` was called 
concurrently by another thread and the allocator decided to give 
the excess space to someone else.


[0]: 
https://dlang.org/phobos/std_experimental_allocator_building_blocks.html
[1]: 
https://dlang.org/phobos/std_experimental_allocator.html#.IAllocator.allocate
[2]: 
https://dlang.org/phobos/std_experimental_allocator.html#.IAllocator.goodAllocSize
[3]: 
https://dlang.org/phobos/std_experimental_allocator.html#.IAllocator.expand




Re: std.expreimantal.allocator deallocate

2021-01-24 Thread vitamin via Digitalmars-d-learn

On Sunday, 24 January 2021 at 14:56:25 UTC, Paul Backus wrote:

On Sunday, 24 January 2021 at 11:00:17 UTC, vitamin wrote:
It is Ok when I call deallocate with smaller slice or I need 
track exact lengtht?


It depends on the specific allocator, but in general, it is 
only guaranteed to work correctly if the slice you pass to 
deallocate is exactly the same as the one you got from allocate.


thanks,
is guaranteed this:

void[] data = Allocator.allocate(data_size);
assert(data.length == data_size)


or can be data.length >= data_size ?


Re: std.expreimantal.allocator deallocate

2021-01-24 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 24 January 2021 at 11:00:17 UTC, vitamin wrote:
It is Ok when I call deallocate with smaller slice or I need 
track exact lengtht?


It depends on the specific allocator, but in general, it is only 
guaranteed to work correctly if the slice you pass to deallocate 
is exactly the same as the one you got from allocate.


std.expreimantal.allocator deallocate

2021-01-24 Thread vitamin via Digitalmars-d-learn
Allocators from std.expreimantal.allocator allocate memory and 
return slice void[] to allocated memory.
Method deallocate has as parameter void[] slice to allocated 
memory.


It is Ok when I call deallocate with smaller slice or I need 
track exact lengtht?

Example:

import std.experimental.allocator : theAllocator;
import core.lifetime : emplace;
import std.stdio;


class Base{
int i;
}
class Derived : Base{
int j;
}

Base make(){
void[] x = theAllocator.allocate(__traits(classInstanceSize, 
Derived));

writeln("allocate: ", x.length);
emplace!Derived(x);
return cast(Derived)x.ptr;
}

void destruct(Base base){
void[] x = (cast(void*)base)[0 .. __traits(classInstanceSize, 
Base)];

writeln("deallocate: ", x.length);
theAllocator.deallocate(x);
}
void main(){
Base x = make;
scope(exit)destruct(x);

///some code...
}

//print:
//allocate: 24
//deallocate: 20