mbed OS5

Fork of UIPEthernet by Zoltan Hudak

Committer:
hudakz
Date:
Sat Dec 20 11:10:40 2014 +0000
Revision:
3:5b17e4656dd0
Child:
4:d774541a34da
02 Name clash with "Ethernet" fixed for LPC1768

Who changed what in which revision?

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