Embedded WebSockets Experiment

Dependencies:   mbed MD5

Committer:
nandgate
Date:
Tue Jul 26 05:30:53 2011 +0000
Revision:
0:6dee052a3fa4

        

Who changed what in which revision?

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