Sign In
Forgot Password?
Sign In | | Create Account

Dynamic memory in real time systems - a solution?

C++ has been on my mind lately. There are many reasons why embedded developers are wary – possibly even afraid – of C++. These include code bloat, execution performance and unreliability resulting from dynamic memory allocation. They are all issues with which engineers should concern themselves, however, none of them are intrinsic problems with the C++ language, as they can all be controlled and contained.

The last on this list of concerns – dynamic memory allocation – I find particularly interesting …

In broad terms, I would say that dynamic allocation of memory in a real time system is a very bad idea. This is for two key reasons, both associated with the standard allocation function malloc(). First, an allocation call is non-deterministic – never good news when predictability of performance is a key requirement. Second, an allocation request may fail in a somewhat unpredictable manner. This is because of heap fragmentation – there is plenty of free memory available, but no contiguous block is large enough for a given request. In this example, there is 6K of free memory, but a request for a block larger than 3K will fail.

Image

I have written about this here before and, in more detail, in a white paper.

Of course, there is a solution. Just about every real time operating system [RTOS] around provides facilities for the deterministic allocation of fixed size memory blocks. You simply set up a “pool” of blocks during initialization and request and release blocks as required. The allocation time is predictable and the failure mode well defined and controlled. Of course, fixed size blocks sound restricting, but that is not the case for many types of application. If you really want to have something that looks like malloc(), you can easily write one. All that is needed is a set of memory pools with exponentially increasing block size. The new allocation function simply requests a large enough block from the appropriate pool.

In C++, the new operator essentially hides a call to malloc(), so rewriting this function addresses the issue. Another approach [which I was reminded about this week by Peter Bushell - thanks Peter] can be more efficient. When you instantiate a C++ class [for struct], the new operator is used to allocate space for its data. When you define a class, you can overload new to make it behave in a class-specific way. A good approach is to define a memory pool for each class, with blocks of precisely the required size. The size of the pools [i.e. number of blocks] depends on the usage of the class, but can be determined quite straightforwardly.

More Blog Posts

About Colin Walls Follow on Twitter

Colin WallsI have over twenty-five years experience in the electronics industry, largely dedicated to embedded software. A frequent presenter at conferences and seminars and author of numerous technical articles and two books on embedded software, I am a member of the marketing team of the Mentor Graphics Embedded Systems Division, and am based in the UK. Away from work, I have a wide range of interests including photography and trying to point my two daughters in the right direction in life. Learn more about Colin, including his go-to karaoke song and the best parts of being British: http://go.mentor.com/3_acv Visit The Colin Walls Blog

More Posts by Colin Walls

Comments 4

Post a Comment
Better still, you don't have to write the new and delete operators for each class. It is possible to design a class template which your can inherit to get this functionality. I designed such a class called Pooled. The difficult bit was getting it to reserve (statically) a pool for its derived objects. In theory, you can't do it before or during construction of the first object (although some compilers coped with my original attempt) because the compiler cannot be relied upon to get know the size of an incomplete object. However, I cracked it in the end! Although I'm currently updating this (and other) software, there's a working version on my blog, for subscribers. To save your having to subscribe, Colin, I'll email you a copy!

Peter Bushell
6:56 PM May 7, 2014

Thanks Peter. As always, I appreciate your input.

Colin Walls
11:31 AM May 8, 2014

Or even better....dont use dynamic allocation. C++ doesn't force you to any more than c does. However, if you're forced into it, overloading new/delete is the way to syntactically make managing fixed pools easier.

Russell Schultz
2:09 PM May 21, 2014

I agree Russell.

Colin Walls
4:03 PM May 22, 2014

Add Your Comment

Please complete the following information to comment or sign in.

(Your email will not be published)

Archives

 
Online Chat