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:
Wed Dec 21 16:58:10 2016 +0100
Revision:
0:e3fb1267e3c3
Child:
19:e416943f7119
initial release

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 0:e3fb1267e3c3 22
cassyarduino 0:e3fb1267e3c3 23 #define POOLOFFSET 1
cassyarduino 0:e3fb1267e3c3 24
cassyarduino 0:e3fb1267e3c3 25 struct memblock MemoryPool::blocks[MEMPOOL_NUM_MEMBLOCKS+1];
cassyarduino 0:e3fb1267e3c3 26
cassyarduino 0:e3fb1267e3c3 27 void
cassyarduino 0:e3fb1267e3c3 28 MemoryPool::init()
cassyarduino 0:e3fb1267e3c3 29 {
cassyarduino 0:e3fb1267e3c3 30 memset(&blocks[0], 0, sizeof(blocks));
cassyarduino 0:e3fb1267e3c3 31 blocks[POOLSTART].begin = MEMPOOL_STARTADDRESS;
cassyarduino 0:e3fb1267e3c3 32 blocks[POOLSTART].size = 0;
cassyarduino 0:e3fb1267e3c3 33 blocks[POOLSTART].nextblock = NOBLOCK;
cassyarduino 0:e3fb1267e3c3 34 }
cassyarduino 0:e3fb1267e3c3 35
cassyarduino 0:e3fb1267e3c3 36 memhandle
cassyarduino 0:e3fb1267e3c3 37 MemoryPool::allocBlock(memaddress size)
cassyarduino 0:e3fb1267e3c3 38 {
cassyarduino 0:e3fb1267e3c3 39 memblock* best = NULL;
cassyarduino 0:e3fb1267e3c3 40 memhandle cur = POOLSTART;
cassyarduino 0:e3fb1267e3c3 41 memblock* block = &blocks[POOLSTART];
cassyarduino 0:e3fb1267e3c3 42 memaddress bestsize = MEMPOOL_SIZE + 1;
cassyarduino 0:e3fb1267e3c3 43
cassyarduino 0:e3fb1267e3c3 44 do
cassyarduino 0:e3fb1267e3c3 45 {
cassyarduino 0:e3fb1267e3c3 46 memhandle next = block->nextblock;
cassyarduino 0:e3fb1267e3c3 47 memaddress freesize = ( next == NOBLOCK ? blocks[POOLSTART].begin + MEMPOOL_SIZE : blocks[next].begin) - block->begin - block->size;
cassyarduino 0:e3fb1267e3c3 48 if (freesize == size)
cassyarduino 0:e3fb1267e3c3 49 {
cassyarduino 0:e3fb1267e3c3 50 best = &blocks[cur];
cassyarduino 0:e3fb1267e3c3 51 goto found;
cassyarduino 0:e3fb1267e3c3 52 }
cassyarduino 0:e3fb1267e3c3 53 if (freesize > size && freesize < bestsize)
cassyarduino 0:e3fb1267e3c3 54 {
cassyarduino 0:e3fb1267e3c3 55 bestsize = freesize;
cassyarduino 0:e3fb1267e3c3 56 best = &blocks[cur];
cassyarduino 0:e3fb1267e3c3 57 }
cassyarduino 0:e3fb1267e3c3 58 if (next == NOBLOCK)
cassyarduino 0:e3fb1267e3c3 59 {
cassyarduino 0:e3fb1267e3c3 60 if (best)
cassyarduino 0:e3fb1267e3c3 61 goto found;
cassyarduino 0:e3fb1267e3c3 62 else
cassyarduino 0:e3fb1267e3c3 63 goto collect;
cassyarduino 0:e3fb1267e3c3 64 }
cassyarduino 0:e3fb1267e3c3 65 block = &blocks[next];
cassyarduino 0:e3fb1267e3c3 66 cur = next;
cassyarduino 0:e3fb1267e3c3 67 }
cassyarduino 0:e3fb1267e3c3 68 while (true);
cassyarduino 0:e3fb1267e3c3 69
cassyarduino 0:e3fb1267e3c3 70 collect:
cassyarduino 0:e3fb1267e3c3 71 {
cassyarduino 0:e3fb1267e3c3 72 cur = POOLSTART;
cassyarduino 0:e3fb1267e3c3 73 block = &blocks[POOLSTART];
cassyarduino 0:e3fb1267e3c3 74 memhandle next;
cassyarduino 0:e3fb1267e3c3 75 while ((next = block->nextblock) != NOBLOCK)
cassyarduino 0:e3fb1267e3c3 76 {
cassyarduino 0:e3fb1267e3c3 77 memaddress dest = block->begin + block->size;
cassyarduino 0:e3fb1267e3c3 78 memblock* nextblock = &blocks[next];
cassyarduino 0:e3fb1267e3c3 79 memaddress* src = &nextblock->begin;
cassyarduino 0:e3fb1267e3c3 80 if (dest != *src)
cassyarduino 0:e3fb1267e3c3 81 {
cassyarduino 0:e3fb1267e3c3 82 #ifdef MEMPOOL_MEMBLOCK_MV
cassyarduino 0:e3fb1267e3c3 83 MEMPOOL_MEMBLOCK_MV(dest,*src,nextblock->size);
cassyarduino 0:e3fb1267e3c3 84 #endif
cassyarduino 0:e3fb1267e3c3 85 *src = dest;
cassyarduino 0:e3fb1267e3c3 86 }
cassyarduino 0:e3fb1267e3c3 87 block = nextblock;
cassyarduino 0:e3fb1267e3c3 88 }
cassyarduino 0:e3fb1267e3c3 89 if (blocks[POOLSTART].begin + MEMPOOL_SIZE - block->begin - block->size >= size)
cassyarduino 0:e3fb1267e3c3 90 best = block;
cassyarduino 0:e3fb1267e3c3 91 else
cassyarduino 0:e3fb1267e3c3 92 goto notfound;
cassyarduino 0:e3fb1267e3c3 93 }
cassyarduino 0:e3fb1267e3c3 94
cassyarduino 0:e3fb1267e3c3 95 found:
cassyarduino 0:e3fb1267e3c3 96 {
cassyarduino 0:e3fb1267e3c3 97 block = &blocks[POOLOFFSET];
cassyarduino 0:e3fb1267e3c3 98 for (cur = POOLOFFSET; cur < MEMPOOL_NUM_MEMBLOCKS + POOLOFFSET; cur++)
cassyarduino 0:e3fb1267e3c3 99 {
cassyarduino 0:e3fb1267e3c3 100 if (block->size)
cassyarduino 0:e3fb1267e3c3 101 {
cassyarduino 0:e3fb1267e3c3 102 block++;
cassyarduino 0:e3fb1267e3c3 103 continue;
cassyarduino 0:e3fb1267e3c3 104 }
cassyarduino 0:e3fb1267e3c3 105 memaddress address = best->begin + best->size;
cassyarduino 0:e3fb1267e3c3 106 #ifdef MEMBLOCK_ALLOC
cassyarduino 0:e3fb1267e3c3 107 MEMBLOCK_ALLOC(address,size);
cassyarduino 0:e3fb1267e3c3 108 #endif
cassyarduino 0:e3fb1267e3c3 109 block->begin = address;
cassyarduino 0:e3fb1267e3c3 110 block->size = size;
cassyarduino 0:e3fb1267e3c3 111 block->nextblock = best->nextblock;
cassyarduino 0:e3fb1267e3c3 112 best->nextblock = cur;
cassyarduino 0:e3fb1267e3c3 113 return cur;
cassyarduino 0:e3fb1267e3c3 114 }
cassyarduino 0:e3fb1267e3c3 115 }
cassyarduino 0:e3fb1267e3c3 116
cassyarduino 0:e3fb1267e3c3 117 notfound: return NOBLOCK;
cassyarduino 0:e3fb1267e3c3 118 }
cassyarduino 0:e3fb1267e3c3 119
cassyarduino 0:e3fb1267e3c3 120 void
cassyarduino 0:e3fb1267e3c3 121 MemoryPool::freeBlock(memhandle handle)
cassyarduino 0:e3fb1267e3c3 122 {
cassyarduino 0:e3fb1267e3c3 123 if (handle == NOBLOCK)
cassyarduino 0:e3fb1267e3c3 124 return;
cassyarduino 0:e3fb1267e3c3 125 memblock *b = &blocks[POOLSTART];
cassyarduino 0:e3fb1267e3c3 126
cassyarduino 0:e3fb1267e3c3 127 do
cassyarduino 0:e3fb1267e3c3 128 {
cassyarduino 0:e3fb1267e3c3 129 memhandle next = b->nextblock;
cassyarduino 0:e3fb1267e3c3 130 if (next == handle)
cassyarduino 0:e3fb1267e3c3 131 {
cassyarduino 0:e3fb1267e3c3 132 memblock *f = &blocks[next];
cassyarduino 0:e3fb1267e3c3 133 #ifdef MEMBLOCK_FREE
cassyarduino 0:e3fb1267e3c3 134 MEMBLOCK_FREE(f->begin,f->size);
cassyarduino 0:e3fb1267e3c3 135 #endif
cassyarduino 0:e3fb1267e3c3 136 b->nextblock = f->nextblock;
cassyarduino 0:e3fb1267e3c3 137 f->size = 0;
cassyarduino 0:e3fb1267e3c3 138 f->nextblock = NOBLOCK;
cassyarduino 0:e3fb1267e3c3 139 return;
cassyarduino 0:e3fb1267e3c3 140 }
cassyarduino 0:e3fb1267e3c3 141 if (next == NOBLOCK)
cassyarduino 0:e3fb1267e3c3 142 return;
cassyarduino 0:e3fb1267e3c3 143 b = &blocks[next];
cassyarduino 0:e3fb1267e3c3 144 #if defined(ESP8266)
cassyarduino 0:e3fb1267e3c3 145 // yield();
cassyarduino 0:e3fb1267e3c3 146 #endif
cassyarduino 0:e3fb1267e3c3 147 }
cassyarduino 0:e3fb1267e3c3 148 while (true);
cassyarduino 0:e3fb1267e3c3 149 }
cassyarduino 0:e3fb1267e3c3 150
cassyarduino 0:e3fb1267e3c3 151 void
cassyarduino 0:e3fb1267e3c3 152 MemoryPool::resizeBlock(memhandle handle, memaddress position)
cassyarduino 0:e3fb1267e3c3 153 {
cassyarduino 0:e3fb1267e3c3 154 memblock * block = &blocks[handle];
cassyarduino 0:e3fb1267e3c3 155 block->begin += position;
cassyarduino 0:e3fb1267e3c3 156 block->size -= position;
cassyarduino 0:e3fb1267e3c3 157 }
cassyarduino 0:e3fb1267e3c3 158
cassyarduino 0:e3fb1267e3c3 159 void
cassyarduino 0:e3fb1267e3c3 160 MemoryPool::resizeBlock(memhandle handle, memaddress position, memaddress size)
cassyarduino 0:e3fb1267e3c3 161 {
cassyarduino 0:e3fb1267e3c3 162 memblock * block = &blocks[handle];
cassyarduino 0:e3fb1267e3c3 163 block->begin += position;
cassyarduino 0:e3fb1267e3c3 164 block->size = size;
cassyarduino 0:e3fb1267e3c3 165 }
cassyarduino 0:e3fb1267e3c3 166
cassyarduino 0:e3fb1267e3c3 167 memaddress
cassyarduino 0:e3fb1267e3c3 168 MemoryPool::blockSize(memhandle handle)
cassyarduino 0:e3fb1267e3c3 169 {
cassyarduino 0:e3fb1267e3c3 170 return blocks[handle].size;
cassyarduino 0:e3fb1267e3c3 171 }