ReactOS 0.4.15-dev-8102-g108db8f
memp.c
Go to the documentation of this file.
1
9/*
10 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
11 * All rights reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without modification,
14 * are permitted provided that the following conditions are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright notice,
17 * this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright notice,
19 * this list of conditions and the following disclaimer in the documentation
20 * and/or other materials provided with the distribution.
21 * 3. The name of the author may not be used to endorse or promote products
22 * derived from this software without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
25 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
27 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
29 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
32 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
33 * OF SUCH DAMAGE.
34 *
35 * This file is part of the lwIP TCP/IP stack.
36 *
37 * Author: Adam Dunkels <adam@sics.se>
38 *
39 */
40
41#include "lwip/opt.h"
42
43#include "lwip/memp.h"
44#include "lwip/pbuf.h"
45#include "lwip/udp.h"
46#include "lwip/raw.h"
47#include "lwip/tcp_impl.h"
48#include "lwip/igmp.h"
49#include "lwip/api.h"
50#include "lwip/api_msg.h"
51#include "lwip/tcpip.h"
52#include "lwip/sys.h"
53#include "lwip/timers.h"
54#include "lwip/stats.h"
55#include "netif/etharp.h"
56#include "lwip/ip_frag.h"
57#include "lwip/snmp_structs.h"
58#include "lwip/snmp_msg.h"
59#include "lwip/dns.h"
60#include "netif/ppp_oe.h"
61
62#include <string.h>
63
64#if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */
65
66struct memp {
67 struct memp *next;
68#if MEMP_OVERFLOW_CHECK
69 const char *file;
70 int line;
71#endif /* MEMP_OVERFLOW_CHECK */
72};
73
74#if MEMP_OVERFLOW_CHECK
75/* if MEMP_OVERFLOW_CHECK is turned on, we reserve some bytes at the beginning
76 * and at the end of each element, initialize them as 0xcd and check
77 * them later. */
78/* If MEMP_OVERFLOW_CHECK is >= 2, on every call to memp_malloc or memp_free,
79 * every single element in each pool is checked!
80 * This is VERY SLOW but also very helpful. */
81/* MEMP_SANITY_REGION_BEFORE and MEMP_SANITY_REGION_AFTER can be overridden in
82 * lwipopts.h to change the amount reserved for checking. */
83#ifndef MEMP_SANITY_REGION_BEFORE
84#define MEMP_SANITY_REGION_BEFORE 16
85#endif /* MEMP_SANITY_REGION_BEFORE*/
86#if MEMP_SANITY_REGION_BEFORE > 0
87#define MEMP_SANITY_REGION_BEFORE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_BEFORE)
88#else
89#define MEMP_SANITY_REGION_BEFORE_ALIGNED 0
90#endif /* MEMP_SANITY_REGION_BEFORE*/
91#ifndef MEMP_SANITY_REGION_AFTER
92#define MEMP_SANITY_REGION_AFTER 16
93#endif /* MEMP_SANITY_REGION_AFTER*/
94#if MEMP_SANITY_REGION_AFTER > 0
95#define MEMP_SANITY_REGION_AFTER_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_AFTER)
96#else
97#define MEMP_SANITY_REGION_AFTER_ALIGNED 0
98#endif /* MEMP_SANITY_REGION_AFTER*/
99
100/* MEMP_SIZE: save space for struct memp and for sanity check */
101#define MEMP_SIZE (LWIP_MEM_ALIGN_SIZE(sizeof(struct memp)) + MEMP_SANITY_REGION_BEFORE_ALIGNED)
102#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x) + MEMP_SANITY_REGION_AFTER_ALIGNED)
103
104#else /* MEMP_OVERFLOW_CHECK */
105
106/* No sanity checks
107 * We don't need to preserve the struct memp while not allocated, so we
108 * can save a little space and set MEMP_SIZE to 0.
109 */
110#define MEMP_SIZE 0
111#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x))
112
113#endif /* MEMP_OVERFLOW_CHECK */
114
117static struct memp *memp_tab[MEMP_MAX];
118
119#else /* MEMP_MEM_MALLOC */
120
121#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x))
122
123#endif /* MEMP_MEM_MALLOC */
124
126#if !MEM_USE_POOLS && !MEMP_MEM_MALLOC
127static
128#endif
130#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEM_ALIGN_SIZE(size),
131#include "lwip/memp_std.h"
132};
133
134#if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */
135
137static const u16_t memp_num[MEMP_MAX] = {
138#define LWIP_MEMPOOL(name,num,size,desc) (num),
139#include "lwip/memp_std.h"
140};
141
143#ifdef LWIP_DEBUG
144static const char *memp_desc[MEMP_MAX] = {
145#define LWIP_MEMPOOL(name,num,size,desc) (desc),
146#include "lwip/memp_std.h"
147};
148#endif /* LWIP_DEBUG */
149
150#if MEMP_SEPARATE_POOLS
151
157#define LWIP_MEMPOOL(name,num,size,desc) u8_t memp_memory_ ## name ## _base \
158 [((num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size)))];
159#include "lwip/memp_std.h"
160
162static u8_t *const memp_bases[] = {
163#define LWIP_MEMPOOL(name,num,size,desc) memp_memory_ ## name ## _base,
164#include "lwip/memp_std.h"
165};
166
167#else /* MEMP_SEPARATE_POOLS */
168
171#define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) )
172#include "lwip/memp_std.h"
173];
174
175#endif /* MEMP_SEPARATE_POOLS */
176
177#if MEMP_SANITY_CHECK
181static int
182memp_sanity(void)
183{
184 s16_t i;
185 struct memp *t, *h;
186
187 for (i = 0; i < MEMP_MAX; i++) {
188 t = memp_tab[i];
189 if(t != NULL) {
190 for (h = t->next; (t != NULL) && (h != NULL); t = t->next,
191 h = (((h->next != NULL) && (h->next->next != NULL)) ? h->next->next : NULL)) {
192 if (t == h) {
193 return 0;
194 }
195 }
196 }
197 }
198 return 1;
199}
200#endif /* MEMP_SANITY_CHECK*/
201#if MEMP_OVERFLOW_CHECK
202#if defined(LWIP_DEBUG) && MEMP_STATS
203static const char * memp_overflow_names[] = {
204#define LWIP_MEMPOOL(name,num,size,desc) "/"desc,
205#include "lwip/memp_std.h"
206 };
207#endif
208
216static void
217memp_overflow_check_element_overflow(struct memp *p, u16_t memp_type)
218{
219 u16_t k;
220 u8_t *m;
221#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0
222 m = (u8_t*)p + MEMP_SIZE + memp_sizes[memp_type];
223 for (k = 0; k < MEMP_SANITY_REGION_AFTER_ALIGNED; k++) {
224 if (m[k] != 0xcd) {
225 char errstr[128] = "detected memp overflow in pool ";
226 char digit[] = "0";
227 if(memp_type >= 10) {
228 digit[0] = '0' + (memp_type/10);
229 strcat(errstr, digit);
230 }
231 digit[0] = '0' + (memp_type%10);
232 strcat(errstr, digit);
233#if defined(LWIP_DEBUG) && MEMP_STATS
234 strcat(errstr, memp_overflow_names[memp_type]);
235#endif
237 }
238 }
239#endif
240}
241
249static void
250memp_overflow_check_element_underflow(struct memp *p, u16_t memp_type)
251{
252 u16_t k;
253 u8_t *m;
254#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0
255 m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED;
256 for (k = 0; k < MEMP_SANITY_REGION_BEFORE_ALIGNED; k++) {
257 if (m[k] != 0xcd) {
258 char errstr[128] = "detected memp underflow in pool ";
259 char digit[] = "0";
260 if(memp_type >= 10) {
261 digit[0] = '0' + (memp_type/10);
262 strcat(errstr, digit);
263 }
264 digit[0] = '0' + (memp_type%10);
265 strcat(errstr, digit);
266#if defined(LWIP_DEBUG) && MEMP_STATS
267 strcat(errstr, memp_overflow_names[memp_type]);
268#endif
270 }
271 }
272#endif
273}
274
280static void
281memp_overflow_check_all(void)
282{
283 u16_t i, j;
284 struct memp *p;
285
286 p = (struct memp *)LWIP_MEM_ALIGN(memp_memory);
287 for (i = 0; i < MEMP_MAX; ++i) {
288 p = p;
289 for (j = 0; j < memp_num[i]; ++j) {
290 memp_overflow_check_element_overflow(p, i);
291 p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED);
292 }
293 }
294 p = (struct memp *)LWIP_MEM_ALIGN(memp_memory);
295 for (i = 0; i < MEMP_MAX; ++i) {
296 p = p;
297 for (j = 0; j < memp_num[i]; ++j) {
298 memp_overflow_check_element_underflow(p, i);
299 p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED);
300 }
301 }
302}
303
307static void
308memp_overflow_init(void)
309{
310 u16_t i, j;
311 struct memp *p;
312 u8_t *m;
313
314 p = (struct memp *)LWIP_MEM_ALIGN(memp_memory);
315 for (i = 0; i < MEMP_MAX; ++i) {
316 p = p;
317 for (j = 0; j < memp_num[i]; ++j) {
318#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0
319 m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED;
320 memset(m, 0xcd, MEMP_SANITY_REGION_BEFORE_ALIGNED);
321#endif
322#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0
323 m = (u8_t*)p + MEMP_SIZE + memp_sizes[i];
324 memset(m, 0xcd, MEMP_SANITY_REGION_AFTER_ALIGNED);
325#endif
326 p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED);
327 }
328 }
329}
330#endif /* MEMP_OVERFLOW_CHECK */
331
337void
339{
340 struct memp *memp;
341 u16_t i, j;
342
343 for (i = 0; i < MEMP_MAX; ++i) {
348 }
349
350#if !MEMP_SEPARATE_POOLS
351 memp = (struct memp *)LWIP_MEM_ALIGN(memp_memory);
352#endif /* !MEMP_SEPARATE_POOLS */
353 /* for every pool: */
354 for (i = 0; i < MEMP_MAX; ++i) {
355 memp_tab[i] = NULL;
356#if MEMP_SEPARATE_POOLS
357 memp = (struct memp*)memp_bases[i];
358#endif /* MEMP_SEPARATE_POOLS */
359 /* create a linked list of memp elements */
360 for (j = 0; j < memp_num[i]; ++j) {
361 memp->next = memp_tab[i];
362 memp_tab[i] = memp;
363 memp = (struct memp *)(void *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i]
365 + MEMP_SANITY_REGION_AFTER_ALIGNED
366#endif
367 );
368 }
369 }
370#if MEMP_OVERFLOW_CHECK
371 memp_overflow_init();
372 /* check everything a first time to see if it worked */
373 memp_overflow_check_all();
374#endif /* MEMP_OVERFLOW_CHECK */
375}
376
388void *
389#if !MEMP_OVERFLOW_CHECK
391#else
392memp_malloc_fn(memp_t type, const char* file, const int line)
393#endif
394{
395 struct memp *memp;
396 SYS_ARCH_DECL_PROTECT(old_level);
397
398 LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;);
399
400 SYS_ARCH_PROTECT(old_level);
401#if MEMP_OVERFLOW_CHECK >= 2
402 memp_overflow_check_all();
403#endif /* MEMP_OVERFLOW_CHECK >= 2 */
404
405 memp = memp_tab[type];
406
407 if (memp != NULL) {
409#if MEMP_OVERFLOW_CHECK
410 memp->next = NULL;
411 memp->file = file;
412 memp->line = line;
413#endif /* MEMP_OVERFLOW_CHECK */
415 LWIP_ASSERT("memp_malloc: memp properly aligned",
416 ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0);
417 memp = (struct memp*)(void *)((u8_t*)memp + MEMP_SIZE);
418 } else {
419 LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", memp_desc[type]));
421 }
422
423 SYS_ARCH_UNPROTECT(old_level);
424
425 return memp;
426}
427
434void
436{
437 struct memp *memp;
438 SYS_ARCH_DECL_PROTECT(old_level);
439
440 if (mem == NULL) {
441 return;
442 }
443 LWIP_ASSERT("memp_free: mem properly aligned",
444 ((mem_ptr_t)mem % MEM_ALIGNMENT) == 0);
445
446 memp = (struct memp *)(void *)((u8_t*)mem - MEMP_SIZE);
447
448 SYS_ARCH_PROTECT(old_level);
449#if MEMP_OVERFLOW_CHECK
450#if MEMP_OVERFLOW_CHECK >= 2
451 memp_overflow_check_all();
452#else
453 memp_overflow_check_element_overflow(memp, type);
454 memp_overflow_check_element_underflow(memp, type);
455#endif /* MEMP_OVERFLOW_CHECK >= 2 */
456#endif /* MEMP_OVERFLOW_CHECK */
457
459
460 memp->next = memp_tab[type];
461 memp_tab[type] = memp;
462
463#if MEMP_SANITY_CHECK
464 LWIP_ASSERT("memp sanity", memp_sanity());
465#endif /* MEMP_SANITY_CHECK */
466
467 SYS_ARCH_UNPROTECT(old_level);
468}
469
470#endif /* MEMP_MEM_MALLOC */
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
static int used
Definition: adh-main.c:39
static int avail
Definition: adh-main.c:39
#define MEM_ALIGNMENT
Definition: d3d9_helpers.c:15
#define NULL
Definition: types.h:112
#define SYS_ARCH_UNPROTECT(lev)
Definition: cc.h:56
signed short s16_t
Definition: cc.h:29
#define SYS_ARCH_PROTECT(lev)
Definition: cc.h:55
#define SYS_ARCH_DECL_PROTECT(lev)
Definition: cc.h:54
ULONG_PTR mem_ptr_t
Definition: cc.h:33
unsigned char u8_t
Definition: cc.h:23
unsigned short u16_t
Definition: cc.h:24
#define LWIP_DBG_LEVEL_SERIOUS
Definition: debug.h:47
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:95
#define LWIP_ERROR(message, expression, handler)
Definition: debug.h:74
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:66
#define LWIP_MEM_ALIGN(addr)
Definition: mem.h:116
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble GLdouble t
Definition: gl.h:2047
GLfloat GLfloat p
Definition: glext.h:8902
const GLfloat * m
Definition: glext.h:10848
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define MEMP_DEBUG
Definition: lwipopts.h:150
static const u16_t memp_num[MEMP_MAX]
Definition: memp.c:137
static u8_t memp_memory[MEM_ALIGNMENT - 1 #define LWIP_MEMPOOL(name, num, size, desc)]
Definition: memp.c:173
static const u16_t memp_sizes[MEMP_MAX]
Definition: memp.c:129
#define MEMP_SIZE
Definition: memp.c:110
static struct memp * memp_tab[MEMP_MAX]
Definition: memp.c:117
void memp_init(void)
Definition: memp.c:338
void * memp_malloc(memp_t type)
Definition: memp.c:390
void memp_free(memp_t type, void *mem)
Definition: memp.c:435
memp_t
Definition: memp.h:43
@ MEMP_MAX
Definition: memp.h:46
int k
Definition: mpi.c:3369
#define MEMP_OVERFLOW_CHECK
Definition: opt.h:154
#define err(...)
#define memset(x, y, z)
Definition: compat.h:39
#define MEMP_STATS_INC_USED(x, i)
Definition: stats.h:255
#define MEMP_STATS_INC(x, i)
Definition: stats.h:253
#define MEMP_STATS_AVAIL(x, i, y)
Definition: stats.h:252
#define MEMP_STATS_DEC(x, i)
Definition: stats.h:254
Definition: fci.c:127
Definition: parser.c:49
Definition: mem.c:156
Definition: memp.c:66
struct memp * next
Definition: memp.c:67
#define max(a, b)
Definition: svc.c:63
const char * errstr(int errcode)