[ODE] Memory Management Proposal

Tanguy Fautre tanguy.fautre at spaceapplications.com
Tue Oct 11 10:46:51 MST 2005


Hi,


While there are still some patches from STABLE that have to be applied 
to the UNSTABLE branch (still on my TODO list ;-)). I've been thinking 
about improving the memory management of ODE.

Basically, we need to use ODE in a real-time environment, hence my 
motivation to improve a few things.

Currently, ODE has two way of allocating the memory in dWorld*Step 
functions:


1. On-the-stack: ODE allocates everything on the stack (this is the 
default behaviour).

Pros:
+ It's fast, with a real-time behaviour (allocation occurs in O(1)).

Cons:
- The application has almost no control on the stack size (at best it 
can be specified at compile/link time).
- ODE crashes when memory demands exceed the stack size (this is really 
bad IMHO).


2. On-the-heap: by defining dUSE_MALLOC_FOR_ALLOCA when compiling ODE, 
malloc/free will be used for memory allocation.

Pros:
+ Memory usage scale with applications demands
+ ODE does not crash when memory demands exceed available ressources, 
but uses a flag system to alert that ODE is out of memory.

Cons:
- This flag system is not thread-safe.
- The application has no control on how much memory ODE can use.
- Malloc/free is slow.
- Inherently not real-time.


I've been currently working on a "Stack Allocator" class (or SA, see 
attached sources), which tries to avoid the disadvantages of the above 
solutions, while keeping their advantages. The ultimate goal would be to 
remove the current ODE allocators, and use this one instead.

Note it's not yet integrated into ODE. But anyway, here is how it should 
work:

- Each dWorld object has its own allocator (making it thread-safe 
between different dWorld objects).

- An allocation failure raises an exception, that will be catched *in* 
ODE and will call an application callback (this would remove a *lot* of 
code that is currently used to test wether malloc has succeeded or not).

- The application callback is registered per dWorld object, making it 
threadsafe and OO friendly.

- The SA has a minimum and a maximum size (by default respectively 0 and 
infinity).

- When ODE memory usage is below (or equal to) the minimum SA size, the 
memory allocation is guaranteed to happen in O(1).

- When ODE memory usage is above the maximum size, the application 
callback will be called (the SA simply raises an exception).

- When ODE memory usage is between minimum and maximum, dynamic memory 
allocation occurs by allocating one or more stacks.

- An application could control whether ODE should automatically adjust 
the minimum stack size next time (if ODE memory usage went above the 
minimum size).


To get the legacy on-the-stack behaviour, the application just has to 
set the minimum and maximum SA size to the same value.

To get the legacy On-the-heap behaviour, the application just has to set 
the minimum SA size to 0 and the maximum SA size to infinity.


The idea is that it's up to the application to decide how much memory 
it's ready to use to keep a real-time behaviour, but that ODE won't 
break if it cannot meet the application expectations.


Keep in mind that for the moment only the implementation of the SA 
itself is done, but the integration with ODE (and the new API functions) 
have yet to be done.

Any comments are welcome.

Yours,

Tanguy




More information about the ODE mailing list