[chuck-users] push but no pop?
Robert Poor
rdpoor at gmail.com
Sun Apr 12 16:54:03 EDT 2009
This note contains a coding tip, a feature request and a bug report.
In that order.
CODING TIP:
Resource pools are a simple way to avoid memory allocation. This
should be old hat to veteran coders, but I remember thinking this was
a cool technique when I first saw it. This is important in embedded
systems (that lack malloc()/free()) and also in ChucK (which doesn't
GC heap-allocated objects). The concept is simple: you keep an array
(a "pool") of available items. When you want an item, you take one
out of the pool, or create one if the pool was empty. When you're
done with the item, you just chuck it back in the pool for the next
time someone wants it.
The code is simple. Let's say you created some structure, like a
NoteEvent, that you'll be using heavily in your ChucK code. By
"heavily", I mean you'll be creating thousands of these every second:
public class NoteEvent {
float frequency;
float commercial_potential;
int makes_adults_complain;
}
How do you keep ChucK's memory from getting silted up? Use a resource
pool. Here's the code.
NoteEvent @ _noteEventPool[0];
fun NoteEvent allocateNoteEvent() {
null @=> NoteEvent @ noteEvent;
if ((_pool.size() => int size) > 0) {
// pop a NoteEvent from the end of the _pool, if available
_pool[size-1] @=> noteEvent;
size-1 => _pool.size;
} else {
// the pool is empty, create a new one
new NoteEvent @=> noteEvent;
}
return noteEvent;
}
fun void freeNoteEvent(NoteEvent @ noteEvent) {
// push noteEvent onto the pool so it's available for the next
// call to allocateNoteEvent().
_pool << noteEvent;
}
Call allocateNoteEvent() when you need a noteEvent, call
freeNoteEvent() when you're done with it. You're responsible for
freeing them when you're done with them -- it's not automatic -- but
if you free each event that you allocate, ChucK will not allocate any
memory above what' needed.
FEATURE REQUEST
As written, array's popBack() function has a void return. It would be
nice if popBack() returned the element it removed, so we could write
the code like this:
fun NoteEvent allocateNoteEvent() {
null @=> NoteEvent @ noteEvent;
if (_pool.size() > 0) {
_pool.popBack() @=> noteEvent;
} else {
new NoteEvent @=> noteEvent;
}
return noteEvent;
}
BUG REPORT
This may be operator error rather than a bug, but the following code:
fun Element allocateElement() {
if ((_pool.size() => int size) > 0) {
_pool[size-1] @=> Element @ element;
size-1 => _pool.size;
return element;
}
return new Element;
}
reports:
chuck(20184,0xa018a830) malloc: *** error for object 0x5eb6e0: double
free
*** set a breakpoint in malloc_error_break to debug
I think the problem may be in "return new Element" -- it may be trying
to return the Element itself, rather than a reference to the Element.
If that's the case, though, it seems like something that should be
caught at compile time.
- Rob
More information about the chuck-users
mailing list