[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