3 ms·
If you need to allocate and free objects from multiple threads, you could put a mutex around the necessary reads and writes. But why would you when you can jus
by frogtoss 3y ago
If you need to allocate and free objects from multiple threads, you could put a mutex around the necessary reads and writes. But why would you when you can just have a pool per-thread and then merge them at a global sync boundary? You can have contentionless allocation this way, which is not something you get with system malloc.
It's out of scope for the article, but you can add watertight generational checks to all handle-to-record accesses by encoding the allocation generation in the upper bits of a handle, then checking them against the record's current generation on handle-to-record resolution.
In practice this throws a breakpoint with diagnostic logging at what would be the equivalent of a method call, which in nicer than a stale context (this) pointer that may or may not be immediately be at the point of violation. It makes bugs more shallow and is an improvement. You can also add things to handles in debug mode, such as the frame number, line and file that it was allocated that you cannot as easily with a pointer.
In practice you end up with more than 16 bytes of overhead management, but you get it back because arrays of handles can be 32-bit instead of 64-bit pointers. But if that sort of thing bothers you, you may want to look into allocation housekeeping. How do you think free knows how much memory to free up? Isn't that tracked per-malloc? In either case, this is happening in your address space.