Example program with HTTPServer and sensor data streaming over TCPSockets, using Donatien Garnier's Net APIs and services code on top of LWIP. Files StreamServer.h and .cpp encapsulate streaming over TCPSockets. Broadcast is done by sendToAll(), and all incoming data is echoed back to the client. Echo code can be replaced with some remote control of the streaming interface. See main() that shows how to periodically send some data to all subscribed clients. To subscribe, a client should open a socket at <mbed_ip> port 123. I used few lines in TCL code to set up a quick sink for the data. HTTP files are served on port 80 concurrently to the streaming.

Dependencies:   mbed

Committer:
iva2k
Date:
Mon Jun 14 03:24:33 2010 +0000
Revision:
1:3ee499525aa5
Parent:
0:e614f7875b60

        

Who changed what in which revision?

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