My fork of the HTTPServer (working)

Dependents:   DGWWebServer LAN2

Committer:
screamer
Date:
Tue Nov 20 12:18:53 2012 +0000
Revision:
1:284f2df30cf9
Parent:
0:7a64fbb4069d
local changes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
screamer 0:7a64fbb4069d 1 /**
screamer 0:7a64fbb4069d 2 * @file
screamer 0:7a64fbb4069d 3 * Dynamic pool memory manager
screamer 0:7a64fbb4069d 4 *
screamer 0:7a64fbb4069d 5 * lwIP has dedicated pools for many structures (netconn, protocol control blocks,
screamer 0:7a64fbb4069d 6 * packet buffers, ...). All these pools are managed here.
screamer 0:7a64fbb4069d 7 */
screamer 0:7a64fbb4069d 8
screamer 0:7a64fbb4069d 9 /*
screamer 0:7a64fbb4069d 10 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
screamer 0:7a64fbb4069d 11 * All rights reserved.
screamer 0:7a64fbb4069d 12 *
screamer 0:7a64fbb4069d 13 * Redistribution and use in source and binary forms, with or without modification,
screamer 0:7a64fbb4069d 14 * are permitted provided that the following conditions are met:
screamer 0:7a64fbb4069d 15 *
screamer 0:7a64fbb4069d 16 * 1. Redistributions of source code must retain the above copyright notice,
screamer 0:7a64fbb4069d 17 * this list of conditions and the following disclaimer.
screamer 0:7a64fbb4069d 18 * 2. Redistributions in binary form must reproduce the above copyright notice,
screamer 0:7a64fbb4069d 19 * this list of conditions and the following disclaimer in the documentation
screamer 0:7a64fbb4069d 20 * and/or other materials provided with the distribution.
screamer 0:7a64fbb4069d 21 * 3. The name of the author may not be used to endorse or promote products
screamer 0:7a64fbb4069d 22 * derived from this software without specific prior written permission.
screamer 0:7a64fbb4069d 23 *
screamer 0:7a64fbb4069d 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
screamer 0:7a64fbb4069d 25 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
screamer 0:7a64fbb4069d 26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
screamer 0:7a64fbb4069d 27 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
screamer 0:7a64fbb4069d 28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
screamer 0:7a64fbb4069d 29 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
screamer 0:7a64fbb4069d 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
screamer 0:7a64fbb4069d 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
screamer 0:7a64fbb4069d 32 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
screamer 0:7a64fbb4069d 33 * OF SUCH DAMAGE.
screamer 0:7a64fbb4069d 34 *
screamer 0:7a64fbb4069d 35 * This file is part of the lwIP TCP/IP stack.
screamer 0:7a64fbb4069d 36 *
screamer 0:7a64fbb4069d 37 * Author: Adam Dunkels <adam@sics.se>
screamer 0:7a64fbb4069d 38 *
screamer 0:7a64fbb4069d 39 */
screamer 0:7a64fbb4069d 40
screamer 0:7a64fbb4069d 41 #include "lwip/opt.h"
screamer 0:7a64fbb4069d 42
screamer 0:7a64fbb4069d 43 #include "lwip/memp.h"
screamer 0:7a64fbb4069d 44 #include "lwip/pbuf.h"
screamer 0:7a64fbb4069d 45 #include "lwip/udp.h"
screamer 0:7a64fbb4069d 46 #include "lwip/raw.h"
screamer 0:7a64fbb4069d 47 #include "lwip/tcp.h"
screamer 0:7a64fbb4069d 48 #include "lwip/igmp.h"
screamer 0:7a64fbb4069d 49 #include "lwip/api.h"
screamer 0:7a64fbb4069d 50 #include "lwip/api_msg.h"
screamer 0:7a64fbb4069d 51 #include "lwip/tcpip.h"
screamer 0:7a64fbb4069d 52 #include "lwip/sys.h"
screamer 0:7a64fbb4069d 53 #include "lwip/stats.h"
screamer 0:7a64fbb4069d 54 #include "netif/etharp.h"
screamer 0:7a64fbb4069d 55 #include "lwip/ip_frag.h"
screamer 0:7a64fbb4069d 56
screamer 0:7a64fbb4069d 57 #include <string.h>
screamer 0:7a64fbb4069d 58
screamer 0:7a64fbb4069d 59 #if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */
screamer 0:7a64fbb4069d 60
screamer 0:7a64fbb4069d 61 struct memp {
screamer 0:7a64fbb4069d 62 struct memp *next;
screamer 0:7a64fbb4069d 63 #if MEMP_OVERFLOW_CHECK
screamer 0:7a64fbb4069d 64 const char *file;
screamer 0:7a64fbb4069d 65 int line;
screamer 0:7a64fbb4069d 66 #endif /* MEMP_OVERFLOW_CHECK */
screamer 0:7a64fbb4069d 67 };
screamer 0:7a64fbb4069d 68
screamer 0:7a64fbb4069d 69 #if MEMP_OVERFLOW_CHECK
screamer 0:7a64fbb4069d 70 /* if MEMP_OVERFLOW_CHECK is turned on, we reserve some bytes at the beginning
screamer 0:7a64fbb4069d 71 * and at the end of each element, initialize them as 0xcd and check
screamer 0:7a64fbb4069d 72 * them later. */
screamer 0:7a64fbb4069d 73 /* If MEMP_OVERFLOW_CHECK is >= 2, on every call to memp_malloc or memp_free,
screamer 0:7a64fbb4069d 74 * every single element in each pool is checked!
screamer 0:7a64fbb4069d 75 * This is VERY SLOW but also very helpful. */
screamer 0:7a64fbb4069d 76 /* MEMP_SANITY_REGION_BEFORE and MEMP_SANITY_REGION_AFTER can be overridden in
screamer 0:7a64fbb4069d 77 * lwipopts.h to change the amount reserved for checking. */
screamer 0:7a64fbb4069d 78 #ifndef MEMP_SANITY_REGION_BEFORE
screamer 0:7a64fbb4069d 79 #define MEMP_SANITY_REGION_BEFORE 16
screamer 0:7a64fbb4069d 80 #endif /* MEMP_SANITY_REGION_BEFORE*/
screamer 0:7a64fbb4069d 81 #if MEMP_SANITY_REGION_BEFORE > 0
screamer 0:7a64fbb4069d 82 #define MEMP_SANITY_REGION_BEFORE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_BEFORE)
screamer 0:7a64fbb4069d 83 #else
screamer 0:7a64fbb4069d 84 #define MEMP_SANITY_REGION_BEFORE_ALIGNED 0
screamer 0:7a64fbb4069d 85 #endif /* MEMP_SANITY_REGION_BEFORE*/
screamer 0:7a64fbb4069d 86 #ifndef MEMP_SANITY_REGION_AFTER
screamer 0:7a64fbb4069d 87 #define MEMP_SANITY_REGION_AFTER 16
screamer 0:7a64fbb4069d 88 #endif /* MEMP_SANITY_REGION_AFTER*/
screamer 0:7a64fbb4069d 89 #if MEMP_SANITY_REGION_AFTER > 0
screamer 0:7a64fbb4069d 90 #define MEMP_SANITY_REGION_AFTER_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_AFTER)
screamer 0:7a64fbb4069d 91 #else
screamer 0:7a64fbb4069d 92 #define MEMP_SANITY_REGION_AFTER_ALIGNED 0
screamer 0:7a64fbb4069d 93 #endif /* MEMP_SANITY_REGION_AFTER*/
screamer 0:7a64fbb4069d 94
screamer 0:7a64fbb4069d 95 /* MEMP_SIZE: save space for struct memp and for sanity check */
screamer 0:7a64fbb4069d 96 #define MEMP_SIZE (LWIP_MEM_ALIGN_SIZE(sizeof(struct memp)) + MEMP_SANITY_REGION_BEFORE_ALIGNED)
screamer 0:7a64fbb4069d 97 #define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x) + MEMP_SANITY_REGION_AFTER_ALIGNED)
screamer 0:7a64fbb4069d 98
screamer 0:7a64fbb4069d 99 #else /* MEMP_OVERFLOW_CHECK */
screamer 0:7a64fbb4069d 100
screamer 0:7a64fbb4069d 101 /* No sanity checks
screamer 0:7a64fbb4069d 102 * We don't need to preserve the struct memp while not allocated, so we
screamer 0:7a64fbb4069d 103 * can save a little space and set MEMP_SIZE to 0.
screamer 0:7a64fbb4069d 104 */
screamer 0:7a64fbb4069d 105 #define MEMP_SIZE 0
screamer 0:7a64fbb4069d 106 #define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x))
screamer 0:7a64fbb4069d 107
screamer 0:7a64fbb4069d 108 #endif /* MEMP_OVERFLOW_CHECK */
screamer 0:7a64fbb4069d 109
screamer 0:7a64fbb4069d 110 /** This array holds the first free element of each pool.
screamer 0:7a64fbb4069d 111 * Elements form a linked list. */
screamer 0:7a64fbb4069d 112 static struct memp *memp_tab[MEMP_MAX];
screamer 0:7a64fbb4069d 113
screamer 0:7a64fbb4069d 114 #else /* MEMP_MEM_MALLOC */
screamer 0:7a64fbb4069d 115
screamer 0:7a64fbb4069d 116 #define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x))
screamer 0:7a64fbb4069d 117
screamer 0:7a64fbb4069d 118 #endif /* MEMP_MEM_MALLOC */
screamer 0:7a64fbb4069d 119
screamer 0:7a64fbb4069d 120 /** This array holds the element sizes of each pool. */
screamer 0:7a64fbb4069d 121 #if !MEM_USE_POOLS && !MEMP_MEM_MALLOC
screamer 0:7a64fbb4069d 122 static
screamer 0:7a64fbb4069d 123 #endif
screamer 0:7a64fbb4069d 124 const u16_t memp_sizes[MEMP_MAX] = {
screamer 0:7a64fbb4069d 125 #define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEM_ALIGN_SIZE(size),
screamer 0:7a64fbb4069d 126 #include "lwip/memp_std.h"
screamer 0:7a64fbb4069d 127 };
screamer 0:7a64fbb4069d 128
screamer 0:7a64fbb4069d 129 #if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */
screamer 0:7a64fbb4069d 130
screamer 0:7a64fbb4069d 131 /** This array holds the number of elements in each pool. */
screamer 0:7a64fbb4069d 132 static const u16_t memp_num[MEMP_MAX] = {
screamer 0:7a64fbb4069d 133 #define LWIP_MEMPOOL(name,num,size,desc) (num),
screamer 0:7a64fbb4069d 134 #include "lwip/memp_std.h"
screamer 0:7a64fbb4069d 135 };
screamer 0:7a64fbb4069d 136
screamer 0:7a64fbb4069d 137 /** This array holds a textual description of each pool. */
screamer 0:7a64fbb4069d 138 #ifdef LWIP_DEBUG
screamer 0:7a64fbb4069d 139 static const char *memp_desc[MEMP_MAX] = {
screamer 0:7a64fbb4069d 140 #define LWIP_MEMPOOL(name,num,size,desc) (desc),
screamer 0:7a64fbb4069d 141 #include "lwip/memp_std.h"
screamer 0:7a64fbb4069d 142 };
screamer 0:7a64fbb4069d 143 #endif /* LWIP_DEBUG */
screamer 0:7a64fbb4069d 144
screamer 0:7a64fbb4069d 145 /** This is the actual memory used by the pools. */
screamer 0:7a64fbb4069d 146 static u8_t memp_memory[MEM_ALIGNMENT - 1
screamer 0:7a64fbb4069d 147 #define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) )
screamer 0:7a64fbb4069d 148 #include "lwip/memp_std.h"
screamer 0:7a64fbb4069d 149 ];
screamer 0:7a64fbb4069d 150
screamer 0:7a64fbb4069d 151 #if MEMP_SANITY_CHECK
screamer 0:7a64fbb4069d 152 /**
screamer 0:7a64fbb4069d 153 * Check that memp-lists don't form a circle
screamer 0:7a64fbb4069d 154 */
screamer 0:7a64fbb4069d 155 static int
screamer 0:7a64fbb4069d 156 memp_sanity(void)
screamer 0:7a64fbb4069d 157 {
screamer 0:7a64fbb4069d 158 s16_t i, c;
screamer 0:7a64fbb4069d 159 struct memp *m, *n;
screamer 0:7a64fbb4069d 160
screamer 0:7a64fbb4069d 161 for (i = 0; i < MEMP_MAX; i++) {
screamer 0:7a64fbb4069d 162 for (m = memp_tab[i]; m != NULL; m = m->next) {
screamer 0:7a64fbb4069d 163 c = 1;
screamer 0:7a64fbb4069d 164 for (n = memp_tab[i]; n != NULL; n = n->next) {
screamer 0:7a64fbb4069d 165 if (n == m && --c < 0) {
screamer 0:7a64fbb4069d 166 return 0;
screamer 0:7a64fbb4069d 167 }
screamer 0:7a64fbb4069d 168 }
screamer 0:7a64fbb4069d 169 }
screamer 0:7a64fbb4069d 170 }
screamer 0:7a64fbb4069d 171 return 1;
screamer 0:7a64fbb4069d 172 }
screamer 0:7a64fbb4069d 173 #endif /* MEMP_SANITY_CHECK*/
screamer 0:7a64fbb4069d 174 #if MEMP_OVERFLOW_CHECK
screamer 0:7a64fbb4069d 175 /**
screamer 0:7a64fbb4069d 176 * Check if a memp element was victim of an overflow
screamer 0:7a64fbb4069d 177 * (e.g. the restricted area after it has been altered)
screamer 0:7a64fbb4069d 178 *
screamer 0:7a64fbb4069d 179 * @param p the memp element to check
screamer 0:7a64fbb4069d 180 * @param memp_size the element size of the pool p comes from
screamer 0:7a64fbb4069d 181 */
screamer 0:7a64fbb4069d 182 static void
screamer 0:7a64fbb4069d 183 memp_overflow_check_element(struct memp *p, u16_t memp_size)
screamer 0:7a64fbb4069d 184 {
screamer 0:7a64fbb4069d 185 u16_t k;
screamer 0:7a64fbb4069d 186 u8_t *m;
screamer 0:7a64fbb4069d 187 #if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0
screamer 0:7a64fbb4069d 188 m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED;
screamer 0:7a64fbb4069d 189 for (k = 0; k < MEMP_SANITY_REGION_BEFORE_ALIGNED; k++) {
screamer 0:7a64fbb4069d 190 if (m[k] != 0xcd) {
screamer 0:7a64fbb4069d 191 LWIP_ASSERT("detected memp underflow!", 0);
screamer 0:7a64fbb4069d 192 }
screamer 0:7a64fbb4069d 193 }
screamer 0:7a64fbb4069d 194 #endif
screamer 0:7a64fbb4069d 195 #if MEMP_SANITY_REGION_AFTER_ALIGNED > 0
screamer 0:7a64fbb4069d 196 m = (u8_t*)p + MEMP_SIZE + memp_size;
screamer 0:7a64fbb4069d 197 for (k = 0; k < MEMP_SANITY_REGION_AFTER_ALIGNED; k++) {
screamer 0:7a64fbb4069d 198 if (m[k] != 0xcd) {
screamer 0:7a64fbb4069d 199 LWIP_ASSERT("detected memp overflow!", 0);
screamer 0:7a64fbb4069d 200 }
screamer 0:7a64fbb4069d 201 }
screamer 0:7a64fbb4069d 202 #endif
screamer 0:7a64fbb4069d 203 }
screamer 0:7a64fbb4069d 204
screamer 0:7a64fbb4069d 205 /**
screamer 0:7a64fbb4069d 206 * Do an overflow check for all elements in every pool.
screamer 0:7a64fbb4069d 207 *
screamer 0:7a64fbb4069d 208 * @see memp_overflow_check_element for a description of the check
screamer 0:7a64fbb4069d 209 */
screamer 0:7a64fbb4069d 210 static void
screamer 0:7a64fbb4069d 211 memp_overflow_check_all(void)
screamer 0:7a64fbb4069d 212 {
screamer 0:7a64fbb4069d 213 u16_t i, j;
screamer 0:7a64fbb4069d 214 struct memp *p;
screamer 0:7a64fbb4069d 215
screamer 0:7a64fbb4069d 216 p = LWIP_MEM_ALIGN(memp_memory);
screamer 0:7a64fbb4069d 217 for (i = 0; i < MEMP_MAX; ++i) {
screamer 0:7a64fbb4069d 218 p = p;
screamer 0:7a64fbb4069d 219 for (j = 0; j < memp_num[i]; ++j) {
screamer 0:7a64fbb4069d 220 memp_overflow_check_element(p, memp_sizes[i]);
screamer 0:7a64fbb4069d 221 p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED);
screamer 0:7a64fbb4069d 222 }
screamer 0:7a64fbb4069d 223 }
screamer 0:7a64fbb4069d 224 }
screamer 0:7a64fbb4069d 225
screamer 0:7a64fbb4069d 226 /**
screamer 0:7a64fbb4069d 227 * Initialize the restricted areas of all memp elements in every pool.
screamer 0:7a64fbb4069d 228 */
screamer 0:7a64fbb4069d 229 static void
screamer 0:7a64fbb4069d 230 memp_overflow_init(void)
screamer 0:7a64fbb4069d 231 {
screamer 0:7a64fbb4069d 232 u16_t i, j;
screamer 0:7a64fbb4069d 233 struct memp *p;
screamer 0:7a64fbb4069d 234 u8_t *m;
screamer 0:7a64fbb4069d 235
screamer 0:7a64fbb4069d 236 p = LWIP_MEM_ALIGN(memp_memory);
screamer 0:7a64fbb4069d 237 for (i = 0; i < MEMP_MAX; ++i) {
screamer 0:7a64fbb4069d 238 p = p;
screamer 0:7a64fbb4069d 239 for (j = 0; j < memp_num[i]; ++j) {
screamer 0:7a64fbb4069d 240 #if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0
screamer 0:7a64fbb4069d 241 m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED;
screamer 0:7a64fbb4069d 242 memset(m, 0xcd, MEMP_SANITY_REGION_BEFORE_ALIGNED);
screamer 0:7a64fbb4069d 243 #endif
screamer 0:7a64fbb4069d 244 #if MEMP_SANITY_REGION_AFTER_ALIGNED > 0
screamer 0:7a64fbb4069d 245 m = (u8_t*)p + MEMP_SIZE + memp_sizes[i];
screamer 0:7a64fbb4069d 246 memset(m, 0xcd, MEMP_SANITY_REGION_AFTER_ALIGNED);
screamer 0:7a64fbb4069d 247 #endif
screamer 0:7a64fbb4069d 248 p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED);
screamer 0:7a64fbb4069d 249 }
screamer 0:7a64fbb4069d 250 }
screamer 0:7a64fbb4069d 251 }
screamer 0:7a64fbb4069d 252 #endif /* MEMP_OVERFLOW_CHECK */
screamer 0:7a64fbb4069d 253
screamer 0:7a64fbb4069d 254 /**
screamer 0:7a64fbb4069d 255 * Initialize this module.
screamer 0:7a64fbb4069d 256 *
screamer 0:7a64fbb4069d 257 * Carves out memp_memory into linked lists for each pool-type.
screamer 0:7a64fbb4069d 258 */
screamer 0:7a64fbb4069d 259 void
screamer 0:7a64fbb4069d 260 memp_init(void)
screamer 0:7a64fbb4069d 261 {
screamer 0:7a64fbb4069d 262 struct memp *memp;
screamer 0:7a64fbb4069d 263 u16_t i, j;
screamer 0:7a64fbb4069d 264
screamer 0:7a64fbb4069d 265 for (i = 0; i < MEMP_MAX; ++i) {
screamer 0:7a64fbb4069d 266 MEMP_STATS_AVAIL(used, i, 0);
screamer 0:7a64fbb4069d 267 MEMP_STATS_AVAIL(max, i, 0);
screamer 0:7a64fbb4069d 268 MEMP_STATS_AVAIL(err, i, 0);
screamer 0:7a64fbb4069d 269 MEMP_STATS_AVAIL(avail, i, memp_num[i]);
screamer 0:7a64fbb4069d 270 }
screamer 0:7a64fbb4069d 271
screamer 0:7a64fbb4069d 272 memp = (struct memp *)LWIP_MEM_ALIGN(memp_memory);
screamer 0:7a64fbb4069d 273 /* for every pool: */
screamer 0:7a64fbb4069d 274 for (i = 0; i < MEMP_MAX; ++i) {
screamer 0:7a64fbb4069d 275 memp_tab[i] = NULL;
screamer 0:7a64fbb4069d 276 /* create a linked list of memp elements */
screamer 0:7a64fbb4069d 277 for (j = 0; j < memp_num[i]; ++j) {
screamer 0:7a64fbb4069d 278 memp->next = memp_tab[i];
screamer 0:7a64fbb4069d 279 memp_tab[i] = memp;
screamer 0:7a64fbb4069d 280 memp = (struct memp *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i]
screamer 0:7a64fbb4069d 281 #if MEMP_OVERFLOW_CHECK
screamer 0:7a64fbb4069d 282 + MEMP_SANITY_REGION_AFTER_ALIGNED
screamer 0:7a64fbb4069d 283 #endif
screamer 0:7a64fbb4069d 284 );
screamer 0:7a64fbb4069d 285 }
screamer 0:7a64fbb4069d 286 }
screamer 0:7a64fbb4069d 287 #if MEMP_OVERFLOW_CHECK
screamer 0:7a64fbb4069d 288 memp_overflow_init();
screamer 0:7a64fbb4069d 289 /* check everything a first time to see if it worked */
screamer 0:7a64fbb4069d 290 memp_overflow_check_all();
screamer 0:7a64fbb4069d 291 #endif /* MEMP_OVERFLOW_CHECK */
screamer 0:7a64fbb4069d 292 }
screamer 0:7a64fbb4069d 293
screamer 0:7a64fbb4069d 294 /**
screamer 0:7a64fbb4069d 295 * Get an element from a specific pool.
screamer 0:7a64fbb4069d 296 *
screamer 0:7a64fbb4069d 297 * @param type the pool to get an element from
screamer 0:7a64fbb4069d 298 *
screamer 0:7a64fbb4069d 299 * the debug version has two more parameters:
screamer 0:7a64fbb4069d 300 * @param file file name calling this function
screamer 0:7a64fbb4069d 301 * @param line number of line where this function is called
screamer 0:7a64fbb4069d 302 *
screamer 0:7a64fbb4069d 303 * @return a pointer to the allocated memory or a NULL pointer on error
screamer 0:7a64fbb4069d 304 */
screamer 0:7a64fbb4069d 305 void *
screamer 0:7a64fbb4069d 306 #if !MEMP_OVERFLOW_CHECK
screamer 0:7a64fbb4069d 307 memp_malloc(memp_t type)
screamer 0:7a64fbb4069d 308 #else
screamer 0:7a64fbb4069d 309 memp_malloc_fn(memp_t type, const char* file, const int line)
screamer 0:7a64fbb4069d 310 #endif
screamer 0:7a64fbb4069d 311 {
screamer 0:7a64fbb4069d 312 struct memp *memp;
screamer 0:7a64fbb4069d 313 SYS_ARCH_DECL_PROTECT(old_level);
screamer 0:7a64fbb4069d 314
screamer 0:7a64fbb4069d 315 LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;);
screamer 0:7a64fbb4069d 316
screamer 0:7a64fbb4069d 317 SYS_ARCH_PROTECT(old_level);
screamer 0:7a64fbb4069d 318 #if MEMP_OVERFLOW_CHECK >= 2
screamer 0:7a64fbb4069d 319 memp_overflow_check_all();
screamer 0:7a64fbb4069d 320 #endif /* MEMP_OVERFLOW_CHECK >= 2 */
screamer 0:7a64fbb4069d 321
screamer 0:7a64fbb4069d 322 memp = memp_tab[type];
screamer 0:7a64fbb4069d 323
screamer 0:7a64fbb4069d 324 if (memp != NULL) {
screamer 0:7a64fbb4069d 325 memp_tab[type] = memp->next;
screamer 0:7a64fbb4069d 326 #if MEMP_OVERFLOW_CHECK
screamer 0:7a64fbb4069d 327 memp->next = NULL;
screamer 0:7a64fbb4069d 328 memp->file = file;
screamer 0:7a64fbb4069d 329 memp->line = line;
screamer 0:7a64fbb4069d 330 #endif /* MEMP_OVERFLOW_CHECK */
screamer 0:7a64fbb4069d 331 MEMP_STATS_INC_USED(used, type);
screamer 0:7a64fbb4069d 332 LWIP_ASSERT("memp_malloc: memp properly aligned",
screamer 0:7a64fbb4069d 333 ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0);
screamer 0:7a64fbb4069d 334 memp = (struct memp*)((u8_t*)memp + MEMP_SIZE);
screamer 0:7a64fbb4069d 335 } else {
screamer 0:7a64fbb4069d 336 LWIP_DEBUGF(MEMP_DEBUG | 2, ("memp_malloc: out of memory in pool %s\n", memp_desc[type]));
screamer 0:7a64fbb4069d 337 MEMP_STATS_INC(err, type);
screamer 0:7a64fbb4069d 338 }
screamer 0:7a64fbb4069d 339
screamer 0:7a64fbb4069d 340 SYS_ARCH_UNPROTECT(old_level);
screamer 0:7a64fbb4069d 341
screamer 0:7a64fbb4069d 342 return memp;
screamer 0:7a64fbb4069d 343 }
screamer 0:7a64fbb4069d 344
screamer 0:7a64fbb4069d 345 /**
screamer 0:7a64fbb4069d 346 * Put an element back into its pool.
screamer 0:7a64fbb4069d 347 *
screamer 0:7a64fbb4069d 348 * @param type the pool where to put mem
screamer 0:7a64fbb4069d 349 * @param mem the memp element to free
screamer 0:7a64fbb4069d 350 */
screamer 0:7a64fbb4069d 351 void
screamer 0:7a64fbb4069d 352 memp_free(memp_t type, void *mem)
screamer 0:7a64fbb4069d 353 {
screamer 0:7a64fbb4069d 354 struct memp *memp;
screamer 0:7a64fbb4069d 355 SYS_ARCH_DECL_PROTECT(old_level);
screamer 0:7a64fbb4069d 356
screamer 0:7a64fbb4069d 357 if (mem == NULL) {
screamer 0:7a64fbb4069d 358 return;
screamer 0:7a64fbb4069d 359 }
screamer 0:7a64fbb4069d 360 LWIP_ASSERT("memp_free: mem properly aligned",
screamer 0:7a64fbb4069d 361 ((mem_ptr_t)mem % MEM_ALIGNMENT) == 0);
screamer 0:7a64fbb4069d 362
screamer 0:7a64fbb4069d 363 memp = (struct memp *)((u8_t*)mem - MEMP_SIZE);
screamer 0:7a64fbb4069d 364
screamer 0:7a64fbb4069d 365 SYS_ARCH_PROTECT(old_level);
screamer 0:7a64fbb4069d 366 #if MEMP_OVERFLOW_CHECK
screamer 0:7a64fbb4069d 367 #if MEMP_OVERFLOW_CHECK >= 2
screamer 0:7a64fbb4069d 368 memp_overflow_check_all();
screamer 0:7a64fbb4069d 369 #else
screamer 0:7a64fbb4069d 370 memp_overflow_check_element(memp, memp_sizes[type]);
screamer 0:7a64fbb4069d 371 #endif /* MEMP_OVERFLOW_CHECK >= 2 */
screamer 0:7a64fbb4069d 372 #endif /* MEMP_OVERFLOW_CHECK */
screamer 0:7a64fbb4069d 373
screamer 0:7a64fbb4069d 374 MEMP_STATS_DEC(used, type);
screamer 0:7a64fbb4069d 375
screamer 0:7a64fbb4069d 376 memp->next = memp_tab[type];
screamer 0:7a64fbb4069d 377 memp_tab[type] = memp;
screamer 0:7a64fbb4069d 378
screamer 0:7a64fbb4069d 379 #if MEMP_SANITY_CHECK
screamer 0:7a64fbb4069d 380 LWIP_ASSERT("memp sanity", memp_sanity());
screamer 0:7a64fbb4069d 381 #endif /* MEMP_SANITY_CHECK */
screamer 0:7a64fbb4069d 382
screamer 0:7a64fbb4069d 383 SYS_ARCH_UNPROTECT(old_level);
screamer 0:7a64fbb4069d 384 }
screamer 0:7a64fbb4069d 385
screamer 0:7a64fbb4069d 386 #endif /* MEMP_MEM_MALLOC */