Skip to content

Allocators

Malachi edited this page May 14, 2018 · 4 revisions

Conundrum

Though perhaps a contentious topic, I have frequently found the lack of handle or lock-based memory (ala Win16 programming) in embedded design puzzling. There seem to be two camps of thought, which fall into the categories:

a) go ahead and use traditional dynamic allocation.
b) manually manage your memory. memory pools, etc.

I have no beef with either of these approaches. Obviously dynamic allocation is a watch your step affair, and in my own (embedded) code I avoid it pretty consistently. Option b, self-managed memory - pooling, etc. is fully legit but it's so darned manual.

How about another option:

c) fine tunable system managed memory

Managed Memory? This isn't JavaScript, dude!

What does that mean "fine tunable system managed memory"? I bet you think I've gone insane, that I'm gonna suggest you hook up a hard drive so that you can do swapping on your ARM M0. Hang in there!! That's not (exactly) where we're going here..

We start with the rudimentary memory-handle concept. I.E. an actual pointer is only available at the last moment after a lock is issued on the handle. After the pointer is used, it is unlocked and the pointer becomes invalid - potentially forever. Memory itself remains allocated, just not immediately accessible.

This may sound fiddly, and it is. However, committing to this approach yields a few important benefits:

  1. Garbage collection becomes viable. In turn, it's conceivable memory fragmentation in your app could be eliminated.
  2. The choice of memory management becomes a secondary, not primary design decision. One may embark on writing the code and swap in a wholly different management technique later on.
  3. Architecturally this overlays almost 1:1 onto a traditional memory pooling technique, so in some cases the additional fiddly-ness is moot.

The underlying mechanisms are abstracted via template metaprogramming so if you really wanted that hard drive swap to virtual pagefile, it's conceivable. But it's more likely you want a memory pool, or perhaps even repurpose code that was originally memory pooled to conventional allocation.

Fixed-buffer shenanigans

So, not only are we warping time and bringing back 1995-era coding, but also with a few extra tricks (not specifically handle-based) we are cloaking fixed buffers as dynamic memory and then stuffing them into things. Namely the string support does this.

This produces a nifty upside of providing a unified string library which can either be fully dynamic like the std::string you love, or scale down to the footprint of a 1970's era C string while maintaining a shared code base (and therefore calling surface) between the two. Neat!

Clone this wiki locally