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