Used in Live Traffic Update Nokia LCD Display Project

Fork of NetServices by Segundo Equipo

Committer:
rrajan8
Date:
Wed Mar 06 19:07:23 2013 +0000
Revision:
8:92b57208ab99
Parent:
0:ac1725ba162c
This project utilizes mbed's networking features to display live traffic updates on the Nokia LCD using the MapQuest API's Traffic Web Service.

Who changed what in which revision?

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