13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*------------------------------------------------------------------------- 23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Memory Pool Library 33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -------------------------------- 43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project 63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License"); 83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License. 93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at 103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * http://www.apache.org/licenses/LICENSE-2.0 123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software 143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS, 153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and 173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License. 183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*! 203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file 213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Memory pool management. 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemPool.h" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h" 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deInt32.h" 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_SUPPORT_FAILING_POOL_ALLOC) 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry# include "deRandom.h" 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <stdlib.h> 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string.h> 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry INITIAL_PAGE_SIZE = 128, /*!< Size for the first allocated memory page. */ 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MAX_PAGE_SIZE = 8096, /*!< Maximum size for a memory page. */ 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MEM_PAGE_BASE_ALIGN = 4 /*!< Base alignment guarantee for mem page data ptr. */ 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef struct MemPage_s MemPage; 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \internal 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Memory page header. 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Represent a page of memory allocate by a memory pool. 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct MemPage_s 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int capacity; 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int bytesAllocated; 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MemPage* nextPage; 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_SUPPORT_DEBUG_POOLS) 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef struct DebugAlloc_s DebugAlloc; 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct DebugAlloc_s 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void* memPtr; 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DebugAlloc* next; 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Memory pool. 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * A pool of memory from which individual memory allocations can be made. 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * The memory pools don't have a freeing operation for individual allocations, 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * but rather all of the memory allocated from a pool is freed when the pool 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * is destroyed. 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * The pools can be arranged into a hierarchy. If a pool with children is 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * destroyed, all of the children are first recursively destroyed and then 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * the pool itself. 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * The memory pools support a feature where individual allocations can be 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * made to simulate failure (i.e., return null). This can be enabled by 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * creating the root pool with the deMemPool_createFailingRoot() function. 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * When the feature is enabled, also creation of sub-pools occasionally 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * fails. 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct deMemPool_s 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 flags; /*!< Flags. */ 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemPool* parent; /*!< Pointer to parent (null for root pools). */ 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemPoolUtil* util; /*!< Utilities (callbacks etc.). */ 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numChildren; /*!< Number of child pools. */ 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemPool* firstChild; /*!< Pointer to first child pool in linked list. */ 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemPool* prevPool; /*!< Previous pool in parent's linked list. */ 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemPool* nextPool; /*!< Next pool in parent's linked list. */ 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MemPage* currentPage; /*!< Current memory page from which to allocate. */ 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_SUPPORT_FAILING_POOL_ALLOC) 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deBool allowFailing; /*!< Is allocation failure simulation enabled? */ 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deRandom failRandom; /*!< RNG for failing allocations. */ 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_SUPPORT_DEBUG_POOLS) 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deBool enableDebugAllocs; /*!< If true, always allocates using deMalloc(). */ 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DebugAlloc* debugAllocListHead; /*!< List of allocation in debug mode. */ 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int lastAllocatedIndex; /*!< Index of last allocated pool (rootPool only). */ 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int allocIndex; /*!< Allocation index (running counter). */ 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_SUPPORT_POOL_MEMORY_TRACKING) 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int maxMemoryAllocated; /*!< Maximum amount of memory allocated from pools. */ 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int maxMemoryCapacity; /*!< Maximum amount of memory allocated for pools. */ 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \internal 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Initialize a memory page. 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param page Memory page to initialize. 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param capacity Capacity allocated for the memory page. 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 1218eb43bbbb25645f6765f79608da7fea6f2e9d86cJarkko Pöyrystatic void MemPage_init (MemPage* page, size_t capacity) 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry memset(page, 0, sizeof(MemPage)); 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_DEBUG) 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry memset(page + 1, 0xCD, capacity); 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 1278eb43bbbb25645f6765f79608da7fea6f2e9d86cJarkko Pöyry page->capacity = (int)capacity; 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \internal 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Create a new memory page. 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param capacity Capacity for the memory page. 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return The created memory page (or null on failure). 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 1368eb43bbbb25645f6765f79608da7fea6f2e9d86cJarkko Pöyrystatic MemPage* MemPage_create (size_t capacity) 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MemPage* page = (MemPage*)deMalloc(sizeof(MemPage) + capacity); 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!page) 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(deIsAlignedPtr(page+1, MEM_PAGE_BASE_ALIGN)); 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MemPage_init(page, capacity); 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return page; 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \internal 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Destroy a memory page. 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param page Memory page to destroy. 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void MemPage_destroy (MemPage* page) 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_DEBUG) 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Fill with garbage to hopefully catch dangling pointer bugs easier. */ 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8* dataPtr = (deUint8*)(page + 1); 15824ceed3e1acf66512ee25ee75002198b6672879dJarkko Pöyry memset(dataPtr, 0xCD, (size_t)page->capacity); 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deFree(page); 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \internal 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Internal function for creating a new memory pool. 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param parent Parent pool (may be null). 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return The created memory pool (or null on failure). 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic deMemPool* createPoolInternal (deMemPool* parent) 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemPool* pool; 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MemPage* initialPage; 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_SUPPORT_FAILING_POOL_ALLOC) 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (parent && parent->allowFailing) 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((deRandom_getUint32(&parent->failRandom) & 16383) <= 15) 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Init first page. */ 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry initialPage = MemPage_create(INITIAL_PAGE_SIZE); 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!initialPage) 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Alloc pool from initial page. */ 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT((int)sizeof(deMemPool) <= initialPage->capacity); 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pool = (deMemPool*)(initialPage + 1); 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry initialPage->bytesAllocated += (int)sizeof(deMemPool); 1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry memset(pool, 0, sizeof(deMemPool)); 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pool->currentPage = initialPage; 1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Register to parent. */ 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pool->parent = parent; 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (parent) 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry parent->numChildren++; 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (parent->firstChild) parent->firstChild->prevPool = pool; 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pool->nextPool = parent->firstChild; 2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry parent->firstChild = pool; 2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Get utils from parent. */ 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pool->util = parent ? parent->util : DE_NULL; 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_SUPPORT_FAILING_POOL_ALLOC) 2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pool->allowFailing = parent ? parent->allowFailing : DE_FALSE; 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deRandom_init(&pool->failRandom, parent ? deRandom_getUint32(&parent->failRandom) : 0x1234abcd); 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_SUPPORT_DEBUG_POOLS) 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pool->enableDebugAllocs = parent ? parent->enableDebugAllocs : DE_FALSE; 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pool->debugAllocListHead = DE_NULL; 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Pool allocation index. */ 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemPool* root = pool; 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (root->parent) 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry root = root->parent; 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pool == root) 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry root->lastAllocatedIndex = 0; 2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pool->allocIndex = ++root->lastAllocatedIndex; 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* \note Put the index of leaking pool here and add a breakpoint to catch leaks easily. */ 2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/* if (pool->allocIndex == 51) 2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry root = root;*/ 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return pool; 2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Create a new root memory pool. 2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return The created memory pool (or null on failure). 2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 2413c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeMemPool* deMemPool_createRoot (const deMemPoolUtil* util, deUint32 flags) 2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemPool* pool = createPoolInternal(DE_NULL); 2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!pool) 2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_SUPPORT_FAILING_POOL_ALLOC) 2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (flags & DE_MEMPOOL_ENABLE_FAILING_ALLOCS) 2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pool->allowFailing = DE_TRUE; 2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_SUPPORT_DEBUG_POOLS) 2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (flags & DE_MEMPOOL_ENABLE_DEBUG_ALLOCS) 2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pool->enableDebugAllocs = DE_TRUE; 2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pool->debugAllocListHead = DE_NULL; 2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(flags); /* in case no debug features enabled */ 2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Get copy of utilities. */ 2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (util) 2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemPoolUtil* utilCopy = DE_POOL_NEW(pool, deMemPoolUtil); 2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(util->allocFailCallback); 2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!utilCopy) 2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemPool_destroy(pool); 2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry memcpy(utilCopy, util, sizeof(deMemPoolUtil)); 2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pool->util = utilCopy; 2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return pool; 2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Create a sub-pool for an existing memory pool. 2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return The created memory pool (or null on failure). 2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 2813c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeMemPool* deMemPool_create (deMemPool* parent) 2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemPool* pool; 2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(parent); 2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pool = createPoolInternal(parent); 2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!pool && parent->util) 2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry parent->util->allocFailCallback(parent->util->userPointer); 2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return pool; 2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Destroy a memory pool. 2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param pool Pool to be destroyed. 2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Frees all the memory allocated from the pool. Also destroyed any child 2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * pools that the pool has (recursively). 2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid deMemPool_destroy (deMemPool* pool) 2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemPool* iter; 3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemPool* iterNext; 3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_SUPPORT_POOL_MEMORY_TRACKING) 3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Update memory consumption statistics. */ 3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pool->parent) 3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemPool* root = pool->parent; 3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (root->parent) 3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry root = root->parent; 3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry root->maxMemoryAllocated = deMax32(root->maxMemoryAllocated, deMemPool_getNumAllocatedBytes(root, DE_TRUE)); 3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry root->maxMemoryCapacity = deMax32(root->maxMemoryCapacity, deMemPool_getCapacity(root, DE_TRUE)); 3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Destroy all children. */ 3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry iter = pool->firstChild; 3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (iter) 3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry iterNext = iter->nextPool; 3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemPool_destroy(iter); 3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry iter = iterNext; 3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(pool->numChildren == 0); 3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Update pointers. */ 3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pool->prevPool) pool->prevPool->nextPool = pool->nextPool; 3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pool->nextPool) pool->nextPool->prevPool = pool->prevPool; 3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pool->parent) 3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemPool* parent = pool->parent; 3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (parent->firstChild == pool) 3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry parent->firstChild = pool->nextPool; 3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry parent->numChildren--; 3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(parent->numChildren >= 0); 3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_SUPPORT_DEBUG_POOLS) 3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Free all debug allocations. */ 3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pool->enableDebugAllocs) 3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DebugAlloc* alloc = pool->debugAllocListHead; 3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DebugAlloc* next; 3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (alloc) 3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry next = alloc->next; 3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deAlignedFree(alloc->memPtr); 3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deFree(alloc); 3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry alloc = next; 3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pool->debugAllocListHead = DE_NULL; 3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Free pages. */ 3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* \note Pool itself is allocated from first page, so we must not touch the pool after freeing the page! */ 3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MemPage* page = pool->currentPage; 3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MemPage* nextPage; 3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (page) 3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry nextPage = page->nextPage; 3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MemPage_destroy(page); 3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry page = nextPage; 3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Get the number of children for a pool. 3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return The number of (immediate) child pools a memory pool has. 3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint deMemPool_getNumChildren (const deMemPool* pool) 3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return pool->numChildren; 3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Get the number of bytes allocated (by the user) from the pool. 3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param pool Pool pointer. 3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param recurse Is operation recursive to child pools? 3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return The number of bytes allocated by the pool (including child pools 3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * if 'recurse' is true). 3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint deMemPool_getNumAllocatedBytes (const deMemPool* pool, deBool recurse) 3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numAllocatedBytes = 0; 3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MemPage* memPage; 3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (memPage = pool->currentPage; memPage; memPage = memPage->nextPage) 3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numAllocatedBytes += memPage->bytesAllocated; 3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (recurse) 3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemPool* child; 4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (child = pool->firstChild; child; child = child->nextPool) 4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numAllocatedBytes += deMemPool_getNumAllocatedBytes(child, DE_TRUE); 4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return numAllocatedBytes; 4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint deMemPool_getCapacity (const deMemPool* pool, deBool recurse) 4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numCapacityBytes = 0; 4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MemPage* memPage; 4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (memPage = pool->currentPage; memPage; memPage = memPage->nextPage) 4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numCapacityBytes += memPage->capacity; 4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (recurse) 4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemPool* child; 4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (child = pool->firstChild; child; child = child->nextPool) 4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numCapacityBytes += deMemPool_getCapacity(child, DE_TRUE); 4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return numCapacityBytes; 4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4268eb43bbbb25645f6765f79608da7fea6f2e9d86cJarkko PöyryDE_INLINE void* deMemPool_allocInternal (deMemPool* pool, size_t numBytes, deUint32 alignBytes) 4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MemPage* curPage = pool->currentPage; 4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_SUPPORT_FAILING_POOL_ALLOC) 4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pool->allowFailing) 4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((deRandom_getUint32(&pool->failRandom) & 16383) <= 15) 4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_SUPPORT_DEBUG_POOLS) 4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pool->enableDebugAllocs) 4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DebugAlloc* header = DE_NEW(DebugAlloc); 4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void* ptr = deAlignedMalloc(numBytes, alignBytes); 4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!header || !ptr) 4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deFree(header); 4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deAlignedFree(ptr); 4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry header->memPtr = ptr; 4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry header->next = pool->debugAllocListHead; 4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pool->debugAllocListHead = header; 4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ptr; 4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(curPage); 46024ceed3e1acf66512ee25ee75002198b6672879dJarkko Pöyry DE_ASSERT(deIsPowerOfTwo32((int)alignBytes)); 4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void* curPagePtr = (void*)((deUint8*)(curPage + 1) + curPage->bytesAllocated); 4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void* alignedPtr = deAlignPtr(curPagePtr, alignBytes); 4648eb43bbbb25645f6765f79608da7fea6f2e9d86cJarkko Pöyry size_t alignPadding = (size_t)((deUintptr)alignedPtr - (deUintptr)curPagePtr); 4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4668eb43bbbb25645f6765f79608da7fea6f2e9d86cJarkko Pöyry if (numBytes + alignPadding > (size_t)(curPage->capacity - curPage->bytesAllocated)) 4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Does not fit to current page. */ 4698eb43bbbb25645f6765f79608da7fea6f2e9d86cJarkko Pöyry int maxAlignPadding = deMax32(0, ((int)alignBytes)-MEM_PAGE_BASE_ALIGN); 4708eb43bbbb25645f6765f79608da7fea6f2e9d86cJarkko Pöyry int newPageCapacity = deMax32(deMin32(2*curPage->capacity, MAX_PAGE_SIZE), ((int)numBytes)+maxAlignPadding); 4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4728eb43bbbb25645f6765f79608da7fea6f2e9d86cJarkko Pöyry curPage = MemPage_create((size_t)newPageCapacity); 4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!curPage) 4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry curPage->nextPage = pool->currentPage; 4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pool->currentPage = curPage; 4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(curPage->bytesAllocated == 0); 4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry curPagePtr = (void*)(curPage + 1); 4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry alignedPtr = deAlignPtr(curPagePtr, alignBytes); 4838eb43bbbb25645f6765f79608da7fea6f2e9d86cJarkko Pöyry alignPadding = (size_t)((deUintptr)alignedPtr - (deUintptr)curPagePtr); 4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4858eb43bbbb25645f6765f79608da7fea6f2e9d86cJarkko Pöyry DE_ASSERT(numBytes + alignPadding <= (size_t)curPage->capacity); 4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4888eb43bbbb25645f6765f79608da7fea6f2e9d86cJarkko Pöyry curPage->bytesAllocated += (int)(numBytes + alignPadding); 4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return alignedPtr; 4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Allocate memory from a pool. 4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param pool Memory pool to allocate from. 4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param numBytes Number of bytes to allocate. 4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return Pointer to the allocate memory (or null on failure). 4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 4998eb43bbbb25645f6765f79608da7fea6f2e9d86cJarkko Pöyryvoid* deMemPool_alloc (deMemPool* pool, size_t numBytes) 5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void* ptr; 5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(pool); 5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(numBytes > 0); 5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ptr = deMemPool_allocInternal(pool, numBytes, DE_POOL_DEFAULT_ALLOC_ALIGNMENT); 5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!ptr && pool->util) 5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pool->util->allocFailCallback(pool->util->userPointer); 5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ptr; 5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Allocate aligned memory from a pool. 5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param pool Memory pool to allocate from. 5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param numBytes Number of bytes to allocate. 5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param alignBytes Required alignment in bytes, must be power of two. 5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return Pointer to the allocate memory (or null on failure). 5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 5178eb43bbbb25645f6765f79608da7fea6f2e9d86cJarkko Pöyryvoid* deMemPool_alignedAlloc (deMemPool* pool, size_t numBytes, deUint32 alignBytes) 5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void* ptr; 5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(pool); 5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(numBytes > 0); 5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(deIsPowerOfTwo32((int)alignBytes)); 5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ptr = deMemPool_allocInternal(pool, numBytes, alignBytes); 5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(deIsAlignedPtr(ptr, alignBytes)); 5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!ptr && pool->util) 5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pool->util->allocFailCallback(pool->util->userPointer); 5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ptr; 5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Duplicate a piece of memory into a memory pool. 5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param pool Memory pool to allocate from. 5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param ptr Piece of memory to duplicate. 5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return Pointer to the copied memory block (or null on failure). 5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 5368eb43bbbb25645f6765f79608da7fea6f2e9d86cJarkko Pöyryvoid* deMemPool_memDup (deMemPool* pool, const void* ptr, size_t numBytes) 5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void* newPtr = deMemPool_alloc(pool, numBytes); 5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (newPtr) 5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry memcpy(newPtr, ptr, numBytes); 5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return newPtr; 5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Duplicate a string into a memory pool. 5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param pool Memory pool to allocate from. 5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param str String to duplicate. 5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return Pointer to the new string (or null on failure). 5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrychar* deMemPool_strDup (deMemPool* pool, const char* str) 5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5528eb43bbbb25645f6765f79608da7fea6f2e9d86cJarkko Pöyry size_t len = strlen(str); 5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry char* newStr = (char*)deMemPool_alloc(pool, len+1); 5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (newStr) 5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry memcpy(newStr, str, len+1); 5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return newStr; 5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Duplicate a string into a memory pool, with a maximum length. 5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param pool Memory pool to allocate from. 5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param str String to duplicate. 5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \param maxLength Maximum number of characters to duplicate. 5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \return Pointer to the new string (or null on failure). 5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrychar* deMemPool_strnDup (deMemPool* pool, const char* str, int maxLength) 5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5688eb43bbbb25645f6765f79608da7fea6f2e9d86cJarkko Pöyry size_t len = (size_t)deMin32((int)strlen(str), deMax32(0, maxLength)); 5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry char* newStr = (char*)deMemPool_alloc(pool, len + 1); 5708eb43bbbb25645f6765f79608da7fea6f2e9d86cJarkko Pöyry 5718eb43bbbb25645f6765f79608da7fea6f2e9d86cJarkko Pöyry DE_ASSERT(maxLength >= 0); 5728eb43bbbb25645f6765f79608da7fea6f2e9d86cJarkko Pöyry 5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (newStr) 5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry memcpy(newStr, str, len); 5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry newStr[len] = 0; 5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return newStr; 5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_SUPPORT_POOL_MEMORY_TRACKING) 5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint deMemPool_getMaxNumAllocatedBytes (const deMemPool* pool) 5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(pool && !pool->parent); /* must be root */ 5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return deMax32(pool->maxMemoryAllocated, deMemPool_getNumAllocatedBytes(pool, DE_TRUE)); 5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint deMemPool_getMaxCapacity (const deMemPool* pool) 5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(pool && !pool->parent); /* must be root */ 5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return deMax32(pool->maxMemoryCapacity, deMemPool_getCapacity(pool, DE_TRUE)); 5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif 596