(snip on malloc)
(snip, then I wrote)
There's only a fine line between the stuff stored at the end of one
block and at the beginning of the next. I know of one system that
allocated in 16B chunks, and the header was the 12 bytes immediately
preceding the allocated area, and the trailing length was stored in
the four bytes immediately after the allocated area - IOW, in the same
16 byte chunk as the 12 byte header for the next block. One area?
Two?
I suppose if you put both at each end, then you can't tell.
I have seen stories about doubly linked list storing only the XOR
(or difference) between previous and next. You can then go either way
along the list, as long as you start at one end or the other. I don't
know if anyone would do that for malloc().
(snip, I also wrote)
MVS still does that. But I've wondered for decades exactly what
allocation algorithm is used to support that.
I always thought it was linked list, but then I knew it from
the OS/360 days, when programs were smaller. Much of getting
OS/360 to work had to do with squeezing things into less memory.
For OS/360 PCP only 20K bytes of memory were used, allowing 44K
on a 64K machine for a user task. The actual algorithm could have
changed for MVS as long as the user interface is the same.
Apparently not enough
to go find out, though... The obvious answer of some sort of tree
seems far too dynamic and unstable in performance, unless you went to
a self-balancing tree of some sort, and that seems like it would have
too high overhead.
The overhead is high enough that PL/I allocates larger blocks and then
suballocates them itself, as needed.
-- glen