Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
MemPool.cpp
00001 /* 00002 mempool.cpp - sleek implementation of a memory pool 00003 Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de> 00004 All rights reserved. 00005 00006 This program is free software: you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation, either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program. If not, see <http://www.gnu.org/licenses/>. 00018 */ 00019 #include "MemPool.h" 00020 #include <string.h> 00021 00022 #define POOLOFFSET 1 00023 00024 struct memblock MemPool:: blocks[MEMPOOL_NUM_MEMBLOCKS + 1]; 00025 00026 /** 00027 * @brief 00028 * @note 00029 * @param 00030 * @retval 00031 */ 00032 void MemPool::init() { 00033 memset(&blocks[0], 0, sizeof(blocks)); 00034 blocks[POOLSTART].begin = MEMPOOL_STARTADDRESS; 00035 blocks[POOLSTART].size = 0; 00036 blocks[POOLSTART].nextblock = NOBLOCK; 00037 } 00038 00039 /** 00040 * @brief 00041 * @note 00042 * @param 00043 * @retval 00044 */ 00045 memhandle MemPool::allocBlock(memaddress size) { 00046 memblock* best = NULL; 00047 memhandle cur = POOLSTART; 00048 memblock* block = &blocks[POOLSTART]; 00049 memaddress bestsize = MEMPOOL_SIZE + 1; 00050 00051 do { 00052 memhandle next = block->nextblock; 00053 memaddress freesize = (next == NOBLOCK ? blocks[POOLSTART].begin + MEMPOOL_SIZE : blocks[next].begin) - 00054 block->begin - 00055 block->size; 00056 if (freesize == size) { 00057 best = &blocks[cur]; 00058 goto found; 00059 } 00060 00061 if (freesize > size && freesize < bestsize) { 00062 bestsize = freesize; 00063 best = &blocks[cur]; 00064 } 00065 00066 if (next == NOBLOCK) { 00067 if (best) 00068 goto found; 00069 else 00070 goto collect; 00071 } 00072 00073 block = &blocks[next]; 00074 cur = next; 00075 } while (true); 00076 00077 collect: 00078 { 00079 cur = POOLSTART; 00080 block = &blocks[POOLSTART]; 00081 00082 memhandle next; 00083 while ((next = block->nextblock) != NOBLOCK) { 00084 memaddress dest = block->begin + block->size; 00085 memblock* nextblock = &blocks[next]; 00086 memaddress* src = &nextblock->begin; 00087 if (dest != *src) 00088 { 00089 #ifdef MEMPOOL_MEMBLOCK_MV 00090 MEMPOOL_MEMBLOCK_MV(dest, *src, nextblock->size); 00091 #endif 00092 *src = dest; 00093 } 00094 00095 block = nextblock; 00096 } 00097 00098 if (blocks[POOLSTART].begin + MEMPOOL_SIZE - block->begin - block->size >= size) 00099 best = block; 00100 else 00101 goto notfound; 00102 } 00103 00104 found: 00105 { 00106 block = &blocks[POOLOFFSET]; 00107 for (cur = POOLOFFSET; cur < MEMPOOL_NUM_MEMBLOCKS + POOLOFFSET; cur++) { 00108 if (block->size) { 00109 block++; 00110 continue; 00111 } 00112 00113 memaddress address = best->begin + best->size; 00114 #ifdef MEMBLOCK_ALLOC 00115 MEMBLOCK_ALLOC(address, size); 00116 #endif 00117 block->begin = address; 00118 block->size = size; 00119 block->nextblock = best->nextblock; 00120 best->nextblock = cur; 00121 return cur; 00122 } 00123 } 00124 00125 notfound: 00126 return NOBLOCK; 00127 } 00128 00129 /** 00130 * @brief 00131 * @note 00132 * @param 00133 * @retval 00134 */ 00135 void MemPool::freeBlock(memhandle handle) { 00136 if (handle == NOBLOCK) 00137 return; 00138 00139 memblock* b = &blocks[POOLSTART]; 00140 00141 do { 00142 memhandle next = b->nextblock; 00143 if (next == handle) { 00144 memblock* f = &blocks[next]; 00145 #ifdef MEMBLOCK_FREE 00146 MEMBLOCK_FREE(f->begin, f->size); 00147 #endif 00148 b->nextblock = f->nextblock; 00149 f->size = 0; 00150 f->nextblock = NOBLOCK; 00151 return; 00152 } 00153 00154 if (next == NOBLOCK) 00155 return; 00156 b = &blocks[next]; 00157 } while (true); 00158 } 00159 00160 /** 00161 * @brief 00162 * @note 00163 * @param 00164 * @retval 00165 */ 00166 void MemPool::resizeBlock(memhandle handle, memaddress position) { 00167 memblock* block = &blocks[handle]; 00168 block->begin += position; 00169 block->size -= position; 00170 } 00171 00172 /** 00173 * @brief 00174 * @note 00175 * @param 00176 * @retval 00177 */ 00178 void MemPool::resizeBlock(memhandle handle, memaddress position, memaddress size) { 00179 memblock* block = &blocks[handle]; 00180 block->begin += position; 00181 block->size = size; 00182 } 00183 00184 /** 00185 * @brief 00186 * @note 00187 * @param 00188 * @retval 00189 */ 00190 memaddress MemPool::blockSize(memhandle handle) { 00191 return blocks[handle].size; 00192 }
Generated on Sun Feb 26 2023 10:14:23 by
1.7.2