123

Committer:
advxolltm
Date:
Mon Jun 06 16:36:52 2022 +0000
Revision:
19:543c2d21e510
Parent:
9:a156d3de5647
123

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 9:a156d3de5647 1 /*
hudakz 9:a156d3de5647 2 mempool.cpp - sleek implementation of a memory pool
hudakz 9:a156d3de5647 3 Copyright (c) 2013 Norbert Truchsess <norbert.truchsess@t-online.de>
hudakz 9:a156d3de5647 4 All rights reserved.
hudakz 9:a156d3de5647 5
hudakz 9:a156d3de5647 6 This program is free software: you can redistribute it and/or modify
hudakz 9:a156d3de5647 7 it under the terms of the GNU General Public License as published by
hudakz 9:a156d3de5647 8 the Free Software Foundation, either version 3 of the License, or
hudakz 9:a156d3de5647 9 (at your option) any later version.
hudakz 9:a156d3de5647 10
hudakz 9:a156d3de5647 11 This program is distributed in the hope that it will be useful,
hudakz 9:a156d3de5647 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
hudakz 9:a156d3de5647 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
hudakz 9:a156d3de5647 14 GNU General Public License for more details.
hudakz 9:a156d3de5647 15
hudakz 9:a156d3de5647 16 You should have received a copy of the GNU General Public License
hudakz 9:a156d3de5647 17 along with this program. If not, see <http://www.gnu.org/licenses/>.
hudakz 9:a156d3de5647 18 */
hudakz 9:a156d3de5647 19 #include "MemPool.h"
hudakz 9:a156d3de5647 20 #include <string.h>
hudakz 9:a156d3de5647 21
hudakz 9:a156d3de5647 22 #define POOLOFFSET 1
hudakz 9:a156d3de5647 23
hudakz 9:a156d3de5647 24 struct memblock MemPool:: blocks[MEMPOOL_NUM_MEMBLOCKS + 1];
hudakz 9:a156d3de5647 25
hudakz 9:a156d3de5647 26 /**
hudakz 9:a156d3de5647 27 * @brief
hudakz 9:a156d3de5647 28 * @note
hudakz 9:a156d3de5647 29 * @param
hudakz 9:a156d3de5647 30 * @retval
hudakz 9:a156d3de5647 31 */
hudakz 9:a156d3de5647 32 void MemPool::init() {
hudakz 9:a156d3de5647 33 memset(&blocks[0], 0, sizeof(blocks));
hudakz 9:a156d3de5647 34 blocks[POOLSTART].begin = MEMPOOL_STARTADDRESS;
hudakz 9:a156d3de5647 35 blocks[POOLSTART].size = 0;
hudakz 9:a156d3de5647 36 blocks[POOLSTART].nextblock = NOBLOCK;
hudakz 9:a156d3de5647 37 }
hudakz 9:a156d3de5647 38
hudakz 9:a156d3de5647 39 /**
hudakz 9:a156d3de5647 40 * @brief
hudakz 9:a156d3de5647 41 * @note
hudakz 9:a156d3de5647 42 * @param
hudakz 9:a156d3de5647 43 * @retval
hudakz 9:a156d3de5647 44 */
hudakz 9:a156d3de5647 45 memhandle MemPool::allocBlock(memaddress size) {
hudakz 9:a156d3de5647 46 memblock* best = NULL;
hudakz 9:a156d3de5647 47 memhandle cur = POOLSTART;
hudakz 9:a156d3de5647 48 memblock* block = &blocks[POOLSTART];
hudakz 9:a156d3de5647 49 memaddress bestsize = MEMPOOL_SIZE + 1;
hudakz 9:a156d3de5647 50
hudakz 9:a156d3de5647 51 do {
hudakz 9:a156d3de5647 52 memhandle next = block->nextblock;
hudakz 9:a156d3de5647 53 memaddress freesize = (next == NOBLOCK ? blocks[POOLSTART].begin + MEMPOOL_SIZE : blocks[next].begin) -
hudakz 9:a156d3de5647 54 block->begin -
hudakz 9:a156d3de5647 55 block->size;
hudakz 9:a156d3de5647 56 if (freesize == size) {
hudakz 9:a156d3de5647 57 best = &blocks[cur];
hudakz 9:a156d3de5647 58 goto found;
hudakz 9:a156d3de5647 59 }
hudakz 9:a156d3de5647 60
hudakz 9:a156d3de5647 61 if (freesize > size && freesize < bestsize) {
hudakz 9:a156d3de5647 62 bestsize = freesize;
hudakz 9:a156d3de5647 63 best = &blocks[cur];
hudakz 9:a156d3de5647 64 }
hudakz 9:a156d3de5647 65
hudakz 9:a156d3de5647 66 if (next == NOBLOCK) {
hudakz 9:a156d3de5647 67 if (best)
hudakz 9:a156d3de5647 68 goto found;
hudakz 9:a156d3de5647 69 else
hudakz 9:a156d3de5647 70 goto collect;
hudakz 9:a156d3de5647 71 }
hudakz 9:a156d3de5647 72
hudakz 9:a156d3de5647 73 block = &blocks[next];
hudakz 9:a156d3de5647 74 cur = next;
hudakz 9:a156d3de5647 75 } while (true);
hudakz 9:a156d3de5647 76
hudakz 9:a156d3de5647 77 collect:
hudakz 9:a156d3de5647 78 {
hudakz 9:a156d3de5647 79 cur = POOLSTART;
hudakz 9:a156d3de5647 80 block = &blocks[POOLSTART];
hudakz 9:a156d3de5647 81
hudakz 9:a156d3de5647 82 memhandle next;
hudakz 9:a156d3de5647 83 while ((next = block->nextblock) != NOBLOCK) {
hudakz 9:a156d3de5647 84 memaddress dest = block->begin + block->size;
hudakz 9:a156d3de5647 85 memblock* nextblock = &blocks[next];
hudakz 9:a156d3de5647 86 memaddress* src = &nextblock->begin;
hudakz 9:a156d3de5647 87 if (dest != *src)
hudakz 9:a156d3de5647 88 {
hudakz 9:a156d3de5647 89 #ifdef MEMPOOL_MEMBLOCK_MV
hudakz 9:a156d3de5647 90 MEMPOOL_MEMBLOCK_MV(dest, *src, nextblock->size);
hudakz 9:a156d3de5647 91 #endif
hudakz 9:a156d3de5647 92 *src = dest;
hudakz 9:a156d3de5647 93 }
hudakz 9:a156d3de5647 94
hudakz 9:a156d3de5647 95 block = nextblock;
hudakz 9:a156d3de5647 96 }
hudakz 9:a156d3de5647 97
hudakz 9:a156d3de5647 98 if (blocks[POOLSTART].begin + MEMPOOL_SIZE - block->begin - block->size >= size)
hudakz 9:a156d3de5647 99 best = block;
hudakz 9:a156d3de5647 100 else
hudakz 9:a156d3de5647 101 goto notfound;
hudakz 9:a156d3de5647 102 }
hudakz 9:a156d3de5647 103
hudakz 9:a156d3de5647 104 found:
hudakz 9:a156d3de5647 105 {
hudakz 9:a156d3de5647 106 block = &blocks[POOLOFFSET];
hudakz 9:a156d3de5647 107 for (cur = POOLOFFSET; cur < MEMPOOL_NUM_MEMBLOCKS + POOLOFFSET; cur++) {
hudakz 9:a156d3de5647 108 if (block->size) {
hudakz 9:a156d3de5647 109 block++;
hudakz 9:a156d3de5647 110 continue;
hudakz 9:a156d3de5647 111 }
hudakz 9:a156d3de5647 112
hudakz 9:a156d3de5647 113 memaddress address = best->begin + best->size;
hudakz 9:a156d3de5647 114 #ifdef MEMBLOCK_ALLOC
hudakz 9:a156d3de5647 115 MEMBLOCK_ALLOC(address, size);
hudakz 9:a156d3de5647 116 #endif
hudakz 9:a156d3de5647 117 block->begin = address;
hudakz 9:a156d3de5647 118 block->size = size;
hudakz 9:a156d3de5647 119 block->nextblock = best->nextblock;
hudakz 9:a156d3de5647 120 best->nextblock = cur;
hudakz 9:a156d3de5647 121 return cur;
hudakz 9:a156d3de5647 122 }
hudakz 9:a156d3de5647 123 }
hudakz 9:a156d3de5647 124
hudakz 9:a156d3de5647 125 notfound:
hudakz 9:a156d3de5647 126 return NOBLOCK;
hudakz 9:a156d3de5647 127 }
hudakz 9:a156d3de5647 128
hudakz 9:a156d3de5647 129 /**
hudakz 9:a156d3de5647 130 * @brief
hudakz 9:a156d3de5647 131 * @note
hudakz 9:a156d3de5647 132 * @param
hudakz 9:a156d3de5647 133 * @retval
hudakz 9:a156d3de5647 134 */
hudakz 9:a156d3de5647 135 void MemPool::freeBlock(memhandle handle) {
hudakz 9:a156d3de5647 136 if (handle == NOBLOCK)
hudakz 9:a156d3de5647 137 return;
hudakz 9:a156d3de5647 138
hudakz 9:a156d3de5647 139 memblock* b = &blocks[POOLSTART];
hudakz 9:a156d3de5647 140
hudakz 9:a156d3de5647 141 do {
hudakz 9:a156d3de5647 142 memhandle next = b->nextblock;
hudakz 9:a156d3de5647 143 if (next == handle) {
hudakz 9:a156d3de5647 144 memblock* f = &blocks[next];
hudakz 9:a156d3de5647 145 #ifdef MEMBLOCK_FREE
hudakz 9:a156d3de5647 146 MEMBLOCK_FREE(f->begin, f->size);
hudakz 9:a156d3de5647 147 #endif
hudakz 9:a156d3de5647 148 b->nextblock = f->nextblock;
hudakz 9:a156d3de5647 149 f->size = 0;
hudakz 9:a156d3de5647 150 f->nextblock = NOBLOCK;
hudakz 9:a156d3de5647 151 return;
hudakz 9:a156d3de5647 152 }
hudakz 9:a156d3de5647 153
hudakz 9:a156d3de5647 154 if (next == NOBLOCK)
hudakz 9:a156d3de5647 155 return;
hudakz 9:a156d3de5647 156 b = &blocks[next];
hudakz 9:a156d3de5647 157 } while (true);
hudakz 9:a156d3de5647 158 }
hudakz 9:a156d3de5647 159
hudakz 9:a156d3de5647 160 /**
hudakz 9:a156d3de5647 161 * @brief
hudakz 9:a156d3de5647 162 * @note
hudakz 9:a156d3de5647 163 * @param
hudakz 9:a156d3de5647 164 * @retval
hudakz 9:a156d3de5647 165 */
hudakz 9:a156d3de5647 166 void MemPool::resizeBlock(memhandle handle, memaddress position) {
hudakz 9:a156d3de5647 167 memblock* block = &blocks[handle];
hudakz 9:a156d3de5647 168 block->begin += position;
hudakz 9:a156d3de5647 169 block->size -= position;
hudakz 9:a156d3de5647 170 }
hudakz 9:a156d3de5647 171
hudakz 9:a156d3de5647 172 /**
hudakz 9:a156d3de5647 173 * @brief
hudakz 9:a156d3de5647 174 * @note
hudakz 9:a156d3de5647 175 * @param
hudakz 9:a156d3de5647 176 * @retval
hudakz 9:a156d3de5647 177 */
hudakz 9:a156d3de5647 178 void MemPool::resizeBlock(memhandle handle, memaddress position, memaddress size) {
hudakz 9:a156d3de5647 179 memblock* block = &blocks[handle];
hudakz 9:a156d3de5647 180 block->begin += position;
hudakz 9:a156d3de5647 181 block->size = size;
hudakz 9:a156d3de5647 182 }
hudakz 9:a156d3de5647 183
hudakz 9:a156d3de5647 184 /**
hudakz 9:a156d3de5647 185 * @brief
hudakz 9:a156d3de5647 186 * @note
hudakz 9:a156d3de5647 187 * @param
hudakz 9:a156d3de5647 188 * @retval
hudakz 9:a156d3de5647 189 */
hudakz 9:a156d3de5647 190 memaddress MemPool::blockSize(memhandle handle) {
hudakz 9:a156d3de5647 191 return blocks[handle].size;
hudakz 9:a156d3de5647 192 }