ReactOS 0.4.16-dev-297-gc569aee
memp.c
Go to the documentation of this file.
1
14/*
15 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without modification,
19 * are permitted provided that the following conditions are met:
20 *
21 * 1. Redistributions of source code must retain the above copyright notice,
22 * this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright notice,
24 * this list of conditions and the following disclaimer in the documentation
25 * and/or other materials provided with the distribution.
26 * 3. The name of the author may not be used to endorse or promote products
27 * derived from this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
30 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
32 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
34 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
37 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
38 * OF SUCH DAMAGE.
39 *
40 * This file is part of the lwIP TCP/IP stack.
41 *
42 * Author: Adam Dunkels <adam@sics.se>
43 *
44 */
45
46#include "lwip/opt.h"
47
48#include "lwip/memp.h"
49#include "lwip/sys.h"
50#include "lwip/stats.h"
51
52#include <string.h>
53
54/* Make sure we include everything we need for size calculation required by memp_std.h */
55#include "lwip/pbuf.h"
56#include "lwip/raw.h"
57#include "lwip/udp.h"
58#include "lwip/tcp.h"
59#include "lwip/priv/tcp_priv.h"
60#include "lwip/altcp.h"
61#include "lwip/ip4_frag.h"
62#include "lwip/netbuf.h"
63#include "lwip/api.h"
65#include "lwip/priv/api_msg.h"
67#include "lwip/etharp.h"
68#include "lwip/igmp.h"
69#include "lwip/timeouts.h"
70/* needed by default MEMP_NUM_SYS_TIMEOUT */
71#include "netif/ppp/ppp_opts.h"
72#include "lwip/netdb.h"
73#include "lwip/dns.h"
74#include "lwip/priv/nd6_priv.h"
75#include "lwip/ip6_frag.h"
76#include "lwip/mld6.h"
77
78#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEMPOOL_DECLARE(name,num,size,desc)
79#include "lwip/priv/memp_std.h"
80
81const struct memp_desc *const memp_pools[MEMP_MAX] = {
82#define LWIP_MEMPOOL(name,num,size,desc) &memp_ ## name,
83#include "lwip/priv/memp_std.h"
84};
85
86#ifdef LWIP_HOOK_FILENAME
87#include LWIP_HOOK_FILENAME
88#endif
89
90#if MEMP_MEM_MALLOC && MEMP_OVERFLOW_CHECK >= 2
91#undef MEMP_OVERFLOW_CHECK
92/* MEMP_OVERFLOW_CHECK >= 2 does not work with MEMP_MEM_MALLOC, use 1 instead */
93#define MEMP_OVERFLOW_CHECK 1
94#endif
95
96#if MEMP_SANITY_CHECK && !MEMP_MEM_MALLOC
100static int
101memp_sanity(const struct memp_desc *desc)
102{
103 struct memp *t, *h;
104
105 t = *desc->tab;
106 if (t != NULL) {
107 for (h = t->next; (t != NULL) && (h != NULL); t = t->next,
108 h = ((h->next != NULL) ? h->next->next : NULL)) {
109 if (t == h) {
110 return 0;
111 }
112 }
113 }
114
115 return 1;
116}
117#endif /* MEMP_SANITY_CHECK && !MEMP_MEM_MALLOC */
118
119#if MEMP_OVERFLOW_CHECK
127static void
128memp_overflow_check_element(struct memp *p, const struct memp_desc *desc)
129{
130 mem_overflow_check_raw((u8_t *)p + MEMP_SIZE, desc->size, "pool ", desc->desc);
131}
132
136static void
137memp_overflow_init_element(struct memp *p, const struct memp_desc *desc)
138{
139 mem_overflow_init_raw((u8_t *)p + MEMP_SIZE, desc->size);
140}
141
142#if MEMP_OVERFLOW_CHECK >= 2
148static void
149memp_overflow_check_all(void)
150{
151 u16_t i, j;
152 struct memp *p;
153 SYS_ARCH_DECL_PROTECT(old_level);
154 SYS_ARCH_PROTECT(old_level);
155
156 for (i = 0; i < MEMP_MAX; ++i) {
157 p = (struct memp *)LWIP_MEM_ALIGN(memp_pools[i]->base);
158 for (j = 0; j < memp_pools[i]->num; ++j) {
159 memp_overflow_check_element(p, memp_pools[i]);
160 p = LWIP_ALIGNMENT_CAST(struct memp *, ((u8_t *)p + MEMP_SIZE + memp_pools[i]->size + MEM_SANITY_REGION_AFTER_ALIGNED));
161 }
162 }
163 SYS_ARCH_UNPROTECT(old_level);
164}
165#endif /* MEMP_OVERFLOW_CHECK >= 2 */
166#endif /* MEMP_OVERFLOW_CHECK */
167
174void
176{
177#if MEMP_MEM_MALLOC
179#else
180 int i;
181 struct memp *memp;
182
183 *desc->tab = NULL;
184 memp = (struct memp *)LWIP_MEM_ALIGN(desc->base);
185#if MEMP_MEM_INIT
186 /* force memset on pool memory */
187 memset(memp, 0, (size_t)desc->num * (MEMP_SIZE + desc->size
189 + MEM_SANITY_REGION_AFTER_ALIGNED
190#endif
191 ));
192#endif
193 /* create a linked list of memp elements */
194 for (i = 0; i < desc->num; ++i) {
195 memp->next = *desc->tab;
196 *desc->tab = memp;
197#if MEMP_OVERFLOW_CHECK
198 memp_overflow_init_element(memp, desc);
199#endif /* MEMP_OVERFLOW_CHECK */
200 /* cast through void* to get rid of alignment warnings */
201 memp = (struct memp *)(void *)((u8_t *)memp + MEMP_SIZE + desc->size
203 + MEM_SANITY_REGION_AFTER_ALIGNED
204#endif
205 );
206 }
207#if MEMP_STATS
208 desc->stats->avail = desc->num;
209#endif /* MEMP_STATS */
210#endif /* !MEMP_MEM_MALLOC */
211
212#if MEMP_STATS && (defined(LWIP_DEBUG) || LWIP_STATS_DISPLAY)
213 desc->stats->name = desc->desc;
214#endif /* MEMP_STATS && (defined(LWIP_DEBUG) || LWIP_STATS_DISPLAY) */
215}
216
223void
225{
226 u16_t i;
227
228 /* for every pool: */
229 for (i = 0; i < LWIP_ARRAYSIZE(memp_pools); i++) {
231
232#if LWIP_STATS && MEMP_STATS
233 lwip_stats.memp[i] = memp_pools[i]->stats;
234#endif
235 }
236
237#if MEMP_OVERFLOW_CHECK >= 2
238 /* check everything a first time to see if it worked */
239 memp_overflow_check_all();
240#endif /* MEMP_OVERFLOW_CHECK >= 2 */
241}
242
243static void *
244#if !MEMP_OVERFLOW_CHECK
246#else
247do_memp_malloc_pool_fn(const struct memp_desc *desc, const char *file, const int line)
248#endif
249{
250 struct memp *memp;
251 SYS_ARCH_DECL_PROTECT(old_level);
252
253#if MEMP_MEM_MALLOC
254 memp = (struct memp *)mem_malloc(MEMP_SIZE + MEMP_ALIGN_SIZE(desc->size));
255 SYS_ARCH_PROTECT(old_level);
256#else /* MEMP_MEM_MALLOC */
257 SYS_ARCH_PROTECT(old_level);
258
259 memp = *desc->tab;
260#endif /* MEMP_MEM_MALLOC */
261
262 if (memp != NULL) {
263#if !MEMP_MEM_MALLOC
264#if MEMP_OVERFLOW_CHECK == 1
265 memp_overflow_check_element(memp, desc);
266#endif /* MEMP_OVERFLOW_CHECK */
267
268 *desc->tab = memp->next;
269#if MEMP_OVERFLOW_CHECK
270 memp->next = NULL;
271#endif /* MEMP_OVERFLOW_CHECK */
272#endif /* !MEMP_MEM_MALLOC */
273#if MEMP_OVERFLOW_CHECK
274 memp->file = file;
275 memp->line = line;
276#if MEMP_MEM_MALLOC
277 memp_overflow_init_element(memp, desc);
278#endif /* MEMP_MEM_MALLOC */
279#endif /* MEMP_OVERFLOW_CHECK */
280 LWIP_ASSERT("memp_malloc: memp properly aligned",
281 ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0);
282#if MEMP_STATS
283 desc->stats->used++;
284 if (desc->stats->used > desc->stats->max) {
285 desc->stats->max = desc->stats->used;
286 }
287#endif
288 SYS_ARCH_UNPROTECT(old_level);
289 /* cast through u8_t* to get rid of alignment warnings */
290 return ((u8_t *)memp + MEMP_SIZE);
291 } else {
292#if MEMP_STATS
293 desc->stats->err++;
294#endif
295 SYS_ARCH_UNPROTECT(old_level);
296 LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", desc->desc));
297 }
298
299 return NULL;
300}
301
309void *
310#if !MEMP_OVERFLOW_CHECK
312#else
313memp_malloc_pool_fn(const struct memp_desc *desc, const char *file, const int line)
314#endif
315{
316 LWIP_ASSERT("invalid pool desc", desc != NULL);
317 if (desc == NULL) {
318 return NULL;
319 }
320
321#if !MEMP_OVERFLOW_CHECK
323#else
324 return do_memp_malloc_pool_fn(desc, file, line);
325#endif
326}
327
335void *
336#if !MEMP_OVERFLOW_CHECK
338#else
339memp_malloc_fn(memp_t type, const char *file, const int line)
340#endif
341{
342 void *memp;
343 LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;);
344
345#if MEMP_OVERFLOW_CHECK >= 2
346 memp_overflow_check_all();
347#endif /* MEMP_OVERFLOW_CHECK >= 2 */
348
349#if !MEMP_OVERFLOW_CHECK
351#else
352 memp = do_memp_malloc_pool_fn(memp_pools[type], file, line);
353#endif
354
355 return memp;
356}
357
358static void
359do_memp_free_pool(const struct memp_desc *desc, void *mem)
360{
361 struct memp *memp;
362 SYS_ARCH_DECL_PROTECT(old_level);
363
364 LWIP_ASSERT("memp_free: mem properly aligned",
365 ((mem_ptr_t)mem % MEM_ALIGNMENT) == 0);
366
367 /* cast through void* to get rid of alignment warnings */
368 memp = (struct memp *)(void *)((u8_t *)mem - MEMP_SIZE);
369
370 SYS_ARCH_PROTECT(old_level);
371
372#if MEMP_OVERFLOW_CHECK == 1
373 memp_overflow_check_element(memp, desc);
374#endif /* MEMP_OVERFLOW_CHECK */
375
376#if MEMP_STATS
377 desc->stats->used--;
378#endif
379
380#if MEMP_MEM_MALLOC
382 SYS_ARCH_UNPROTECT(old_level);
383 mem_free(memp);
384#else /* MEMP_MEM_MALLOC */
385 memp->next = *desc->tab;
386 *desc->tab = memp;
387
388#if MEMP_SANITY_CHECK
389 LWIP_ASSERT("memp sanity", memp_sanity(desc));
390#endif /* MEMP_SANITY_CHECK */
391
392 SYS_ARCH_UNPROTECT(old_level);
393#endif /* !MEMP_MEM_MALLOC */
394}
395
402void
403memp_free_pool(const struct memp_desc *desc, void *mem)
404{
405 LWIP_ASSERT("invalid pool desc", desc != NULL);
406 if ((desc == NULL) || (mem == NULL)) {
407 return;
408 }
409
411}
412
419void
421{
422#ifdef LWIP_HOOK_MEMP_AVAILABLE
423 struct memp *old_first;
424#endif
425
426 LWIP_ERROR("memp_free: type < MEMP_MAX", (type < MEMP_MAX), return;);
427
428 if (mem == NULL) {
429 return;
430 }
431
432#if MEMP_OVERFLOW_CHECK >= 2
433 memp_overflow_check_all();
434#endif /* MEMP_OVERFLOW_CHECK >= 2 */
435
436#ifdef LWIP_HOOK_MEMP_AVAILABLE
437 old_first = *memp_pools[type]->tab;
438#endif
439
441
442#ifdef LWIP_HOOK_MEMP_AVAILABLE
443 if (old_first == NULL) {
444 LWIP_HOOK_MEMP_AVAILABLE(type);
445 }
446#endif
447}
#define MEM_ALIGNMENT
Definition: d3d9_helpers.c:15
#define LWIP_ARRAYSIZE(x)
Definition: def.h:69
#define mem_free(ptr, bsize)
Definition: types.h:124
#define NULL
Definition: types.h:112
#define SYS_ARCH_UNPROTECT(lev)
Definition: cc.h:39
#define SYS_ARCH_PROTECT(lev)
Definition: cc.h:38
#define SYS_ARCH_DECL_PROTECT(lev)
Definition: cc.h:37
void * mem_malloc(mem_size_t size_in)
Definition: mem.c:831
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:158
#define LWIP_ERROR(message, expression, handler)
Definition: debug.h:130
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:116
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble GLdouble t
Definition: gl.h:2047
GLsizeiptr size
Definition: glext.h:5919
GLfloat GLfloat p
Definition: glext.h:8902
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
uint8_t u8_t
Definition: arch.h:125
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:373
uint16_t u16_t
Definition: arch.h:127
#define LWIP_MEM_ALIGN(addr)
Definition: arch.h:294
#define LWIP_ALIGNMENT_CAST(target_type, val)
Definition: arch.h:245
uintptr_t mem_ptr_t
Definition: arch.h:135
#define LWIP_DBG_LEVEL_SERIOUS
Definition: debug.h:57
#define MEMP_DEBUG
Definition: opt.h:3420
#define MEMP_OVERFLOW_CHECK
Definition: opt.h:303
static void * do_memp_malloc_pool(const struct memp_desc *desc)
Definition: memp.c:245
void memp_free_pool(const struct memp_desc *desc, void *mem)
Definition: memp.c:403
void memp_init_pool(const struct memp_desc *desc)
Definition: memp.c:175
void memp_init(void)
Definition: memp.c:224
static void do_memp_free_pool(const struct memp_desc *desc, void *mem)
Definition: memp.c:359
void * memp_malloc_pool(const struct memp_desc *desc)
Definition: memp.c:311
void * memp_malloc(memp_t type)
Definition: memp.c:337
const struct memp_desc *const memp_pools[MEMP_MAX]
Definition: memp.c:81
void memp_free(memp_t type, void *mem)
Definition: memp.c:420
memp_t
Definition: memp.h:52
@ MEMP_MAX
Definition: memp.h:55
#define MEMP_ALIGN_SIZE(x)
Definition: memp_priv.h:64
#define MEMP_SIZE
Definition: memp_priv.h:63
static const WCHAR desc[]
Definition: protectdata.c:36
#define memset(x, y, z)
Definition: compat.h:39
Definition: fci.c:127
Definition: parser.c:49
Definition: mem.c:349
Definition: memp_priv.h:69
struct memp * next
Definition: memp_priv.h:70