Hey pfalcon, thanks for taking a look at the code and giving all that feedback.
Most of your comments come from (I think) a misunderstanding of the basics of how tinymem works, which is clearly my fault -- if someone like you couldn't understand it then it needs to be better explained. To help facilitate understanding I have written this google doc
https://docs.google.com/document/d/1qxT ... D8l2JyfNE/. I'm pretty sure this is not an impossible problem by using pointer indirection. I will be using this document for development discussion and using the README to give an overview of how the module works.
To answer your questions
I think my README jumped into the gritty details a bit to fast. I've already put a lot of thought into how to optimize tinymem, and the README document currently reflects those thoughts. The document I linked and the future README will be better.
For instance, I am not "allocating to defragment". I have a freed array that store which indexes are free. Deallocation does two steps:
- combines freed indexes that are right next to eachother
- moves data that has a higher location value into empty data (note that without freed bins, this would be VERY slow but still possible)
Ignore the bins of freed for now, they are not necessary and are only used to speed up various aspects of the memory manager. In the simplest (and very very slow) case, allocation would be as follows:
- look through a linear "freed" array for data of lesser or equal size
- if none exists take off the heap.
defragmenting would then clean up any left over holes at a later time.
- "#define TM_MAX_FILLED_PTRS (TM_MAX_POOL_PTRS / 8 + TM_MAX_POOL_PTRS % 8)" was actually a bug, haha. It is supposed to be
(TM_MAX_POOL_PTRS / 8 + (TM_MAX_POOL_PTRS % 8 ? 1 : 0)). It is currently being fixed (and tested for the first time) in the malloc branch.
Summing up: writing good memory manager is hard. No, very hard. The basics of defragmenting memory manager is double pointer indirection + semi-space. Yes, that means giving away more than half of useful memory. If you're interested in defragmenting memory manager for uPy, I suggest you implement that, then try to improve on it. Improving on that will be hard, you immediately will lose on performance (and double-indirection and semispace copying are already a big performance hit).
I would like to convince you that you only need single pointer indirection and you don't have to give away half of the useful memory. I will be fixing up the documentation, and I would love to chat over google hangouts to explain the inner workings if you would like.