[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