Similar what I want, except I don't have hard real-time requirements nor do I want to limit the amount of memory available or use size-classes. Was presented around the same time as I was given the task. Their implementation incl. future work is similar to what I had thought out in the beginning of my thesis work (circa 2008), in particular storing the handle table in the free-list to save memory.
Trivial moving compacting (doesn't yet respect locked handles) that works only in the same K line. Scans for the first (i.e. lowest starting memory address) free slot of the globally largest size. Checks for a chunk with a free and a used component, moves the used one to the free slot and merges the two parts of the chunk into a new (partial) chunk of size (k-1).