UIPEthernet library for Arduino IDE, Eclipse with arduino plugin and MBED/SMeshStudio (AVR,STM32F,ESP8266,Intel ARC32,Nordic nRF51,Teensy boards,Realtek Ameba(RTL8195A,RTL8710)), ENC28j60 network chip. Compatible with Wiznet W5100 Ethernet library API. Compiled and tested on Nucleo-F302R8. Master repository is: https://github.com/UIPEthernet/UIPEthernet/

Committer:
cassyarduino
Date:
Tue Jan 23 15:08:43 2018 +0100
Revision:
39:deeb00b81cc9
Parent:
19:e416943f7119
Release: 2.0.4

Who changed what in which revision?

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