I’m not sure what this means by real-time. Normally a realtime system would be expected to provide some guarantees on worst-case latency and the docs don’t do this.
Executing destructors in a separate thread is often a good idea in general but may have interesting side effects with respect to C++’s expectations of deterministic deallocation. It is also unclear what happens when destructors access their fields via one of these smart pointers. Does it run destructors on garbage cycles and then collect them? What happens if a destructor resurrects an object?
The code has almost no comments and I am deeply distrustful of any memory manager that doesn’t have a very high comment ratio, because they are full of corner cases and the next time you come back to the code it’s important to remember exactly what design decisions you made and how they impact the rest of the system.
What happens if a destructor resurrects an object?
This is a bothersome problem. I heard proposed the following solution: a finaliser should run when an object is dead, but it should not be passed the dead object itself, but instead a secondary object. For example, you might have a ‘file’ object, which wraps a file descriptor and a buffer; a finaliser will be set to run when the file object is dead, but it will only be passed the file descriptor. Hence, it cannot wreck any havoc.
Of course, you have to deal with the case when the finaliser closes over the object to be destroyed. Ideally, an error would be signaled at the point when the finaliser is associated with the object, but that could be unreasonably slow. Alternately, you force the finaliser-object association to be made at object creation time. This is a bit less expressive, but destructors are dangerous enough that that seems like a reasonable restriction.
I’m not sure what this means by real-time. Normally a realtime system would be expected to provide some guarantees on worst-case latency and the docs don’t do this.
Executing destructors in a separate thread is often a good idea in general but may have interesting side effects with respect to C++’s expectations of deterministic deallocation. It is also unclear what happens when destructors access their fields via one of these smart pointers. Does it run destructors on garbage cycles and then collect them? What happens if a destructor resurrects an object?
The code has almost no comments and I am deeply distrustful of any memory manager that doesn’t have a very high comment ratio, because they are full of corner cases and the next time you come back to the code it’s important to remember exactly what design decisions you made and how they impact the rest of the system.
This is a bothersome problem. I heard proposed the following solution: a finaliser should run when an object is dead, but it should not be passed the dead object itself, but instead a secondary object. For example, you might have a ‘file’ object, which wraps a file descriptor and a buffer; a finaliser will be set to run when the file object is dead, but it will only be passed the file descriptor. Hence, it cannot wreck any havoc.
Of course, you have to deal with the case when the finaliser closes over the object to be destroyed. Ideally, an error would be signaled at the point when the finaliser is associated with the object, but that could be unreasonably slow. Alternately, you force the finaliser-object association to be made at object creation time. This is a bit less expressive, but destructors are dangerous enough that that seems like a reasonable restriction.
It also doesn’t have any tests or benchmarks!
FWIW I found the Go garbage collector to be full of useful/interesting comments:
https://github.com/golang/go/blob/master/src/runtime/mgc.go
And to me it shows how readable the language is (even though I don’t use it)