11c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/* 21c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com> 31c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 41c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Permission is hereby granted, free of charge, to any person obtaining a 51c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * copy of this software and associated documentation files (the "Software"), 61c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * to deal in the Software without restriction, including without limitation 71c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * on the rights to use, copy, modify, merge, publish, distribute, sub 81c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * license, and/or sell copies of the Software, and to permit persons to whom 91c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * the Software is furnished to do so, subject to the following conditions: 101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * The above copyright notice and this permission notice (including the next 121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * paragraph) shall be included in all copies or substantial portions of the 131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Software. 141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#ifndef MEMORY_POOL_H 241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#define MEMORY_POOL_H 251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstruct memory_block; 271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Provides a pool of memory that can quickly be allocated from, at the 301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * cost of being unable to explicitly free one of the allocated blocks. 311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Instead, the entire pool can be freed at once. 321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * The idea is to allow one to quickly allocate a flexible amount of 341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * memory during operations like shader compilation while avoiding 351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * reference counting headaches. 361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstruct memory_pool { 381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned char * head; 391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned char * end; 401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int total_allocated; 411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct memory_block * blocks; 421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}; 431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid memory_pool_init(struct memory_pool * pool); 461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid memory_pool_destroy(struct memory_pool * pool); 471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid * memory_pool_malloc(struct memory_pool * pool, unsigned int bytes); 481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Generic helper for growing an array that has separate size/count 521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * and reserved counters to accomodate up to num new element. 531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * type * Array; 551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * unsigned int Size; 561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * unsigned int Reserved; 571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * memory_pool_array_reserve(pool, type, Array, Size, Reserved, k); 591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * assert(Size + k < Reserved); 601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * \note Size is not changed by this macro. 621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * \warning Array, Size, Reserved have to be lvalues and may be evaluated 641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * several times. 651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#define memory_pool_array_reserve(pool, type, array, size, reserved, num) do { \ 671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int _num = (num); \ 681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if ((size) + _num > (reserved)) { \ 691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int newreserve = (reserved) * 2; \ 701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák type * newarray; \ 711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (newreserve < _num) \ 721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák newreserve = 4 * _num; /* arbitrary heuristic */ \ 731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák newarray = memory_pool_malloc((pool), newreserve * sizeof(type)); \ 741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák memcpy(newarray, (array), (size) * sizeof(type)); \ 751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák (array) = newarray; \ 761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák (reserved) = newreserve; \ 771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } \ 781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} while(0) 791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#endif /* MEMORY_POOL_H */ 81