mbed OS5

Fork of UIPEthernet by Zoltan Hudak

Committer:
pilotak
Date:
Sun Aug 06 16:01:26 2017 +0000
Revision:
9:e55652bed36c
Parent:
8:4acb22344932
mBed OS5

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
pilotak 9:e55652bed36c 24 struct memblock myMemoryPool:: blocks[MEMPOOL_NUM_MEMBLOCKS + 1];
hudakz 4:d774541a34da 25
hudakz 3:5b17e4656dd0 26 /**
hudakz 3:5b17e4656dd0 27 * @brief
hudakz 3:5b17e4656dd0 28 * @note
hudakz 3:5b17e4656dd0 29 * @param
hudakz 3:5b17e4656dd0 30 * @retval
hudakz 3:5b17e4656dd0 31 */
pilotak 9:e55652bed36c 32 void myMemoryPool::init(void) {
hudakz 3:5b17e4656dd0 33 memset(&blocks[0], 0, sizeof(blocks));
hudakz 4:d774541a34da 34 blocks[POOLSTART].begin = MEMPOOL_STARTADDRESS;
hudakz 3:5b17e4656dd0 35 blocks[POOLSTART].size = 0;
hudakz 3:5b17e4656dd0 36 blocks[POOLSTART].nextblock = NOBLOCK;
hudakz 3:5b17e4656dd0 37 }
hudakz 3:5b17e4656dd0 38
hudakz 3:5b17e4656dd0 39 /**
hudakz 3:5b17e4656dd0 40 * @brief
hudakz 3:5b17e4656dd0 41 * @note
hudakz 3:5b17e4656dd0 42 * @param
hudakz 3:5b17e4656dd0 43 * @retval
hudakz 3:5b17e4656dd0 44 */
pilotak 9:e55652bed36c 45 memhandle myMemoryPool::allocBlock(memaddress size) {
hudakz 3:5b17e4656dd0 46 memblock* best = NULL;
hudakz 3:5b17e4656dd0 47 memhandle cur = POOLSTART;
hudakz 3:5b17e4656dd0 48 memblock* block = &blocks[POOLSTART];
hudakz 4:d774541a34da 49 memaddress bestsize = MEMPOOL_SIZE + 1;
hudakz 3:5b17e4656dd0 50
hudakz 8:4acb22344932 51 do {
hudakz 3:5b17e4656dd0 52 memhandle next = block->nextblock;
hudakz 4:d774541a34da 53 memaddress freesize = (next == NOBLOCK ? blocks[POOLSTART].begin + MEMPOOL_SIZE : blocks[next].begin) -
hudakz 3:5b17e4656dd0 54 block->begin -
hudakz 3:5b17e4656dd0 55 block->size;
hudakz 8:4acb22344932 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 8:4acb22344932 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 8:4acb22344932 66 if (next == NOBLOCK) {
hudakz 8:4acb22344932 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 8:4acb22344932 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 8:4acb22344932 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 8:4acb22344932 87 if (dest != *src)
hudakz 3:5b17e4656dd0 88 {
hudakz 4:d774541a34da 89 #ifdef MEMPOOL_MEMBLOCK_MV
hudakz 4:d774541a34da 90 MEMPOOL_MEMBLOCK_MV(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 8:4acb22344932 98 if (blocks[POOLSTART].begin + MEMPOOL_SIZE - 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 8:4acb22344932 107 for (cur = POOLOFFSET; cur < MEMPOOL_NUM_MEMBLOCKS + POOLOFFSET; cur++) {
hudakz 8:4acb22344932 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 */
pilotak 9:e55652bed36c 135 void myMemoryPool::freeBlock(memhandle handle) {
hudakz 8:4acb22344932 136 if (handle == NOBLOCK)
hudakz 4:d774541a34da 137 return;
hudakz 4:d774541a34da 138
hudakz 3:5b17e4656dd0 139 memblock* b = &blocks[POOLSTART];
hudakz 3:5b17e4656dd0 140
hudakz 8:4acb22344932 141 do {
hudakz 3:5b17e4656dd0 142 memhandle next = b->nextblock;
hudakz 8:4acb22344932 143 if (next == handle) {
hudakz 3:5b17e4656dd0 144 memblock* f = &blocks[next];
hudakz 3:5b17e4656dd0 145 #ifdef MEMBLOCK_FREE
hudakz 3:5b17e4656dd0 146 MEMBLOCK_FREE(f->begin, f->size);
hudakz 3:5b17e4656dd0 147 #endif
hudakz 3:5b17e4656dd0 148 b->nextblock = f->nextblock;
hudakz 3:5b17e4656dd0 149 f->size = 0;
hudakz 3:5b17e4656dd0 150 f->nextblock = NOBLOCK;
hudakz 3:5b17e4656dd0 151 return;
hudakz 3:5b17e4656dd0 152 }
hudakz 3:5b17e4656dd0 153
hudakz 8:4acb22344932 154 if (next == NOBLOCK)
hudakz 3:5b17e4656dd0 155 return;
hudakz 3:5b17e4656dd0 156 b = &blocks[next];
hudakz 8:4acb22344932 157 } while (true);
hudakz 3:5b17e4656dd0 158 }
hudakz 3:5b17e4656dd0 159
hudakz 3:5b17e4656dd0 160 /**
hudakz 3:5b17e4656dd0 161 * @brief
hudakz 3:5b17e4656dd0 162 * @note
hudakz 3:5b17e4656dd0 163 * @param
hudakz 3:5b17e4656dd0 164 * @retval
hudakz 3:5b17e4656dd0 165 */
pilotak 9:e55652bed36c 166 void myMemoryPool::resizeBlock(memhandle handle, memaddress position) {
hudakz 3:5b17e4656dd0 167 memblock* block = &blocks[handle];
hudakz 3:5b17e4656dd0 168 block->begin += position;
hudakz 3:5b17e4656dd0 169 block->size -= position;
hudakz 3:5b17e4656dd0 170 }
hudakz 3:5b17e4656dd0 171
hudakz 3:5b17e4656dd0 172 /**
hudakz 3:5b17e4656dd0 173 * @brief
hudakz 3:5b17e4656dd0 174 * @note
hudakz 3:5b17e4656dd0 175 * @param
hudakz 3:5b17e4656dd0 176 * @retval
hudakz 3:5b17e4656dd0 177 */
pilotak 9:e55652bed36c 178 void myMemoryPool::resizeBlock(memhandle handle, memaddress position, memaddress size) {
hudakz 3:5b17e4656dd0 179 memblock* block = &blocks[handle];
hudakz 3:5b17e4656dd0 180 block->begin += position;
hudakz 3:5b17e4656dd0 181 block->size = size;
hudakz 3:5b17e4656dd0 182 }
hudakz 3:5b17e4656dd0 183
hudakz 3:5b17e4656dd0 184 /**
hudakz 3:5b17e4656dd0 185 * @brief
hudakz 3:5b17e4656dd0 186 * @note
hudakz 3:5b17e4656dd0 187 * @param
hudakz 3:5b17e4656dd0 188 * @retval
hudakz 3:5b17e4656dd0 189 */
pilotak 9:e55652bed36c 190 memaddress myMemoryPool::blockSize(memhandle handle) {
hudakz 3:5b17e4656dd0 191 return blocks[handle].size;
hudakz 3:5b17e4656dd0 192 }