mbed OS5
Fork of UIPEthernet by
Embed:
(wiki syntax)
Show/hide line numbers
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 myMemoryPool:: blocks[MEMPOOL_NUM_MEMBLOCKS + 1]; 00025 00026 /** 00027 * @brief 00028 * @note 00029 * @param 00030 * @retval 00031 */ 00032 void myMemoryPool::init(void) { 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 myMemoryPool::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 myMemoryPool::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 myMemoryPool::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 myMemoryPool::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 myMemoryPool::blockSize(memhandle handle) { 00191 return blocks[handle].size; 00192 }
Generated on Tue Jul 12 2022 18:10:58 by 1.7.2