Global thread-local free-list allocator

Witold witold.baryluk+dlang at gmail.com
Thu Mar 16 22:35:48 UTC 2023


On Thursday, 16 March 2023 at 20:53:28 UTC, Witold wrote:
>
> It crashes at `new_.value`, as `new_` is `null`
>

It looks like this:

```d
alias VariableAllocator = ThreadLocal!(FreeList!(Mallocator, 
Variable.sizeof, unbounded));
```

should be this instead:

```d
alias VariableAllocator = ThreadLocal!(FreeList!(Mallocator, 
Variable.sizeof, Variable.sizeof));
```

or

```d
alias VariableAllocator = ThreadLocal!(FreeList!(Mallocator, 0, 
Variable.sizeof));
```

Otherwise if the list is empty (which it is at the start), the 
free list will attempt to allocate from `Mallocator.instance`, 
but not at requested size but rather at `maxSize` of the free 
list allocator (that makes sense), which is `unbound`, which is 
`size_t.max`, or about 18446 PiB. `malloc` will return null for 
such crazy amount.


Also using `Mallocator` as a parent might not be a good idea.

The reason is that while it will allocate memory, it will not 
tell GC to scan that area for pointers to other structs. So if 
some objects are allocated using normal GC allocator, and only 
reference is from Mallocator/FreeList allocated struct, GC will 
think this object is unreachable, and clean it up.

Using `GCAllocator` works. I made this handy alias template:

```d
alias ListAllocator(Type) = ThreadLocal!(FreeList!(GCAllocator, 
Type.sizeof, Type.sizeof));
```

Then just in a struct:

```d
struct MyStruct(T) {
   alias allocator = ListAllocator!(MyStruct!T);  // or 
typeof(this)

   ...
   auto m = allocator.instance.make!(MyStruct!T)();
   ...

   allocator.instance.dispose(m);



}



More information about the Digitalmars-d-learn mailing list