digitalmars.D.bugs - [Issue 15353] New: std.experimental.allocator cannot free memory in
- via Digitalmars-d-bugs (62/62) Nov 17 2015 https://issues.dlang.org/show_bug.cgi?id=15353
https://issues.dlang.org/show_bug.cgi?id=15353 Issue ID: 15353 Summary: std.experimental.allocator cannot free memory in its destructor if the GC is an ancestor Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: normal Priority: P1 Component: dmd Assignee: nobody puremagic.com Reporter: andrei erdani.com Brian Schott noticed this and wrote: ============== I've discovered a problem with the interaction between CAllocatorImpl and GCAllocator: CAllocatorImpl cannot have a parent allocator that uses GCAllocator, or a parent that has a parent (and so on) that uses GCAllocator. This is because several of the allocator implementations are structs that deallocate their memory during their destructors. In the case of CAllocatorImpl, this destructor call is often caused by the GC. Calls to the GC fail during destructors called by the GC, so something needs to be done to fix this. Maybe extra logic can be added to the various allocators to check that they are not calling GCAllocator during a destructor, or we can somehow disallow using GC-backed allocators from CAllocatorImpl. Example: https://gist.github.com/Hackerpilot/26c2d0e7b1aa0605b344 ============== To which I replied: ============== I imagine there are a number of ways we can fix this: (a) Allow freeing memory but not allocation during GC. I'm not sure but I suspect that it's memory allocation that mustn't be allowed during a GC cycle. Martin, could you please confirm/deny this? (b) The GC has or should have a primitive that tells code whether a collection is in progress. Then allocator destructors can test that and do nothing if that's the case. (c) Have the GC itself ignore calls to free during a collection cycle. ============== To which Martin Nowak replied: ============== Free also manipulates internal structures. https://github.com/D-Programming-Language/druntime/blob/12ea1075fc24a5389a4e1aa24ae9e177903f85d2/src/gc/gc.d#L873 https://github.com/D-Programming-Language/druntime/blob/12ea1075fc24a5389a4e1aa24ae9e177903f85d2/src/gc/gc.d#L2245 With the current code, it would be very delicate to allow free during finalization. [About having the GC just ignore calls to free during a GC cycle:] Seems like a feasible solution for now. In general the GC isn't reentrant safe, and that will be enforced even stricter by using a non-recursive lock https://trello.com/c/Xp44NwHG/87-ttas-spinlock-for-gc. We do want to get rid of the InvalidMemoryOperation issue, and should revisit it once the thread caches are implemented. During a collection it should be possible to queue most operations and serve allocations (maybe from a separate pool). There are still a lot of rather big changes planned to the GC before it makes sense to look at this particular issue. ============== So it seems a good fix for this bug would be to just have the GC ignore calls to free(). --
Nov 17 2015