One fine day I needed a lock/release memory pool manager.
The application entails a user wandering through scenery that includes rolling landscape with lots of buildings and underground tunnels and whatnot. The overall landscape is tiled, and these data structures are continuously being loaded and unloaded as the user moves across the landscape tiles.
The total amount of memory required for the tiles surrounding the user is much lower than the maximum amount of stuff that could be on one tile times the number of surrounding tiles, so I needed something simple that would let me use a reduced amount of memory to store all this stuff and would deal with fragmentation and merging unused fragments to create larger fragments when needed.
void * init_mem_pool(int chunks, int size, int reuse); void free_mem_pool(void * pool); void * lock_mem_chunk(void * pool, int handle); void release_mem_chunk(void * pool, int handle); void free_mem_chunk(void * pool, int handle); int alloc_mem_chunk(void * pool, int size); void mem_pool_stats(void * pool);
main.c - program I used to beat the bugs out
Makefile for Linux, though it should compile under anything
Getting these things to the point where they're solid can be tricky. To test it, I set the MAX_POOL down to 10000 and MAX_CHUNKS to 10 and then I could set the loop to run through millions of alloc_mem_chunk/free_mem_chunk calls. After I got all the boneheaded bugs out, I was running into more subtle bugs that would only manifest themselves after 100,000 times through the loop. That's typical for memory managers, and they've gotta be tested tested tested. Reproducable sequence random number generators are your friend.