ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

memp.c
Go to the documentation of this file.
00001 
00009 /*
00010  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
00011  * All rights reserved. 
00012  * 
00013  * Redistribution and use in source and binary forms, with or without modification, 
00014  * are permitted provided that the following conditions are met:
00015  *
00016  * 1. Redistributions of source code must retain the above copyright notice,
00017  *    this list of conditions and the following disclaimer.
00018  * 2. Redistributions in binary form must reproduce the above copyright notice,
00019  *    this list of conditions and the following disclaimer in the documentation
00020  *    and/or other materials provided with the distribution.
00021  * 3. The name of the author may not be used to endorse or promote products
00022  *    derived from this software without specific prior written permission. 
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
00025  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
00026  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
00027  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00028  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
00029  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
00031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
00032  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
00033  * OF SUCH DAMAGE.
00034  *
00035  * This file is part of the lwIP TCP/IP stack.
00036  * 
00037  * Author: Adam Dunkels <adam@sics.se>
00038  *
00039  */
00040 
00041 #include "lwip/opt.h"
00042 
00043 #include "lwip/memp.h"
00044 #include "lwip/pbuf.h"
00045 #include "lwip/udp.h"
00046 #include "lwip/raw.h"
00047 #include "lwip/tcp_impl.h"
00048 #include "lwip/igmp.h"
00049 #include "lwip/api.h"
00050 #include "lwip/api_msg.h"
00051 #include "lwip/tcpip.h"
00052 #include "lwip/sys.h"
00053 #include "lwip/timers.h"
00054 #include "lwip/stats.h"
00055 #include "netif/etharp.h"
00056 #include "lwip/ip_frag.h"
00057 #include "lwip/snmp_structs.h"
00058 #include "lwip/snmp_msg.h"
00059 #include "lwip/dns.h"
00060 #include "netif/ppp_oe.h"
00061 
00062 #include <string.h>
00063 
00064 #if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */
00065 
00066 struct memp {
00067   struct memp *next;
00068 #if MEMP_OVERFLOW_CHECK
00069   const char *file;
00070   int line;
00071 #endif /* MEMP_OVERFLOW_CHECK */
00072 };
00073 
00074 #if MEMP_OVERFLOW_CHECK
00075 /* if MEMP_OVERFLOW_CHECK is turned on, we reserve some bytes at the beginning
00076  * and at the end of each element, initialize them as 0xcd and check
00077  * them later. */
00078 /* If MEMP_OVERFLOW_CHECK is >= 2, on every call to memp_malloc or memp_free,
00079  * every single element in each pool is checked!
00080  * This is VERY SLOW but also very helpful. */
00081 /* MEMP_SANITY_REGION_BEFORE and MEMP_SANITY_REGION_AFTER can be overridden in
00082  * lwipopts.h to change the amount reserved for checking. */
00083 #ifndef MEMP_SANITY_REGION_BEFORE
00084 #define MEMP_SANITY_REGION_BEFORE  16
00085 #endif /* MEMP_SANITY_REGION_BEFORE*/
00086 #if MEMP_SANITY_REGION_BEFORE > 0
00087 #define MEMP_SANITY_REGION_BEFORE_ALIGNED    LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_BEFORE)
00088 #else
00089 #define MEMP_SANITY_REGION_BEFORE_ALIGNED    0
00090 #endif /* MEMP_SANITY_REGION_BEFORE*/
00091 #ifndef MEMP_SANITY_REGION_AFTER
00092 #define MEMP_SANITY_REGION_AFTER   16
00093 #endif /* MEMP_SANITY_REGION_AFTER*/
00094 #if MEMP_SANITY_REGION_AFTER > 0
00095 #define MEMP_SANITY_REGION_AFTER_ALIGNED     LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_AFTER)
00096 #else
00097 #define MEMP_SANITY_REGION_AFTER_ALIGNED     0
00098 #endif /* MEMP_SANITY_REGION_AFTER*/
00099 
00100 /* MEMP_SIZE: save space for struct memp and for sanity check */
00101 #define MEMP_SIZE          (LWIP_MEM_ALIGN_SIZE(sizeof(struct memp)) + MEMP_SANITY_REGION_BEFORE_ALIGNED)
00102 #define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x) + MEMP_SANITY_REGION_AFTER_ALIGNED)
00103 
00104 #else /* MEMP_OVERFLOW_CHECK */
00105 
00106 /* No sanity checks
00107  * We don't need to preserve the struct memp while not allocated, so we
00108  * can save a little space and set MEMP_SIZE to 0.
00109  */
00110 #define MEMP_SIZE           0
00111 #define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x))
00112 
00113 #endif /* MEMP_OVERFLOW_CHECK */
00114 
00117 static struct memp *memp_tab[MEMP_MAX];
00118 
00119 #else /* MEMP_MEM_MALLOC */
00120 
00121 #define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x))
00122 
00123 #endif /* MEMP_MEM_MALLOC */
00124 
00126 #if !MEM_USE_POOLS && !MEMP_MEM_MALLOC
00127 static
00128 #endif
00129 const u16_t memp_sizes[MEMP_MAX] = {
00130 #define LWIP_MEMPOOL(name,num,size,desc)  LWIP_MEM_ALIGN_SIZE(size),
00131 #include "lwip/memp_std.h"
00132 };
00133 
00134 #if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */
00135 
00137 static const u16_t memp_num[MEMP_MAX] = {
00138 #define LWIP_MEMPOOL(name,num,size,desc)  (num),
00139 #include "lwip/memp_std.h"
00140 };
00141 
00143 #ifdef LWIP_DEBUG
00144 static const char *memp_desc[MEMP_MAX] = {
00145 #define LWIP_MEMPOOL(name,num,size,desc)  (desc),
00146 #include "lwip/memp_std.h"
00147 };
00148 #endif /* LWIP_DEBUG */
00149 
00150 #if MEMP_SEPARATE_POOLS
00151 
00157 #define LWIP_MEMPOOL(name,num,size,desc) u8_t memp_memory_ ## name ## _base \
00158   [((num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size)))];   
00159 #include "lwip/memp_std.h"
00160 
00162 static u8_t *const memp_bases[] = { 
00163 #define LWIP_MEMPOOL(name,num,size,desc) memp_memory_ ## name ## _base,   
00164 #include "lwip/memp_std.h"
00165 };
00166 
00167 #else /* MEMP_SEPARATE_POOLS */
00168 
00170 static u8_t memp_memory[MEM_ALIGNMENT - 1 
00171 #define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) )
00172 #include "lwip/memp_std.h"
00173 ];
00174 
00175 #endif /* MEMP_SEPARATE_POOLS */
00176 
00177 #if MEMP_SANITY_CHECK
00178 
00181 static int
00182 memp_sanity(void)
00183 {
00184   s16_t i, c;
00185   struct memp *m, *n;
00186 
00187   for (i = 0; i < MEMP_MAX; i++) {
00188     for (m = memp_tab[i]; m != NULL; m = m->next) {
00189       c = 1;
00190       for (n = memp_tab[i]; n != NULL; n = n->next) {
00191         if (n == m && --c < 0) {
00192           return 0;
00193         }
00194       }
00195     }
00196   }
00197   return 1;
00198 }
00199 #endif /* MEMP_SANITY_CHECK*/
00200 #if MEMP_OVERFLOW_CHECK
00201 #if defined(LWIP_DEBUG) && MEMP_STATS
00202 static const char * memp_overflow_names[] = {
00203 #define LWIP_MEMPOOL(name,num,size,desc) "/"desc,
00204 #include "lwip/memp_std.h"
00205   };
00206 #endif
00207 
00215 static void
00216 memp_overflow_check_element_overflow(struct memp *p, u16_t memp_type)
00217 {
00218   u16_t k;
00219   u8_t *m;
00220 #if MEMP_SANITY_REGION_AFTER_ALIGNED > 0
00221   m = (u8_t*)p + MEMP_SIZE + memp_sizes[memp_type];
00222   for (k = 0; k < MEMP_SANITY_REGION_AFTER_ALIGNED; k++) {
00223     if (m[k] != 0xcd) {
00224       char errstr[128] = "detected memp overflow in pool ";
00225       char digit[] = "0";
00226       if(memp_type >= 10) {
00227         digit[0] = '0' + (memp_type/10);
00228         strcat(errstr, digit);
00229       }
00230       digit[0] = '0' + (memp_type%10);
00231       strcat(errstr, digit);
00232 #if defined(LWIP_DEBUG) && MEMP_STATS
00233       strcat(errstr, memp_overflow_names[memp_type]);
00234 #endif
00235       LWIP_ASSERT(errstr, 0);
00236     }
00237   }
00238 #endif
00239 }
00240 
00248 static void
00249 memp_overflow_check_element_underflow(struct memp *p, u16_t memp_type)
00250 {
00251   u16_t k;
00252   u8_t *m;
00253 #if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0
00254   m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED;
00255   for (k = 0; k < MEMP_SANITY_REGION_BEFORE_ALIGNED; k++) {
00256     if (m[k] != 0xcd) {
00257       char errstr[128] = "detected memp underflow in pool ";
00258       char digit[] = "0";
00259       if(memp_type >= 10) {
00260         digit[0] = '0' + (memp_type/10);
00261         strcat(errstr, digit);
00262       }
00263       digit[0] = '0' + (memp_type%10);
00264       strcat(errstr, digit);
00265 #if defined(LWIP_DEBUG) && MEMP_STATS
00266       strcat(errstr, memp_overflow_names[memp_type]);
00267 #endif
00268       LWIP_ASSERT(errstr, 0);
00269     }
00270   }
00271 #endif
00272 }
00273 
00279 static void
00280 memp_overflow_check_all(void)
00281 {
00282   u16_t i, j;
00283   struct memp *p;
00284 
00285   p = (struct memp *)LWIP_MEM_ALIGN(memp_memory);
00286   for (i = 0; i < MEMP_MAX; ++i) {
00287     p = p;
00288     for (j = 0; j < memp_num[i]; ++j) {
00289       memp_overflow_check_element_overflow(p, i);
00290       p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED);
00291     }
00292   }
00293   p = (struct memp *)LWIP_MEM_ALIGN(memp_memory);
00294   for (i = 0; i < MEMP_MAX; ++i) {
00295     p = p;
00296     for (j = 0; j < memp_num[i]; ++j) {
00297       memp_overflow_check_element_underflow(p, i);
00298       p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED);
00299     }
00300   }
00301 }
00302 
00306 static void
00307 memp_overflow_init(void)
00308 {
00309   u16_t i, j;
00310   struct memp *p;
00311   u8_t *m;
00312 
00313   p = (struct memp *)LWIP_MEM_ALIGN(memp_memory);
00314   for (i = 0; i < MEMP_MAX; ++i) {
00315     p = p;
00316     for (j = 0; j < memp_num[i]; ++j) {
00317 #if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0
00318       m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED;
00319       memset(m, 0xcd, MEMP_SANITY_REGION_BEFORE_ALIGNED);
00320 #endif
00321 #if MEMP_SANITY_REGION_AFTER_ALIGNED > 0
00322       m = (u8_t*)p + MEMP_SIZE + memp_sizes[i];
00323       memset(m, 0xcd, MEMP_SANITY_REGION_AFTER_ALIGNED);
00324 #endif
00325       p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED);
00326     }
00327   }
00328 }
00329 #endif /* MEMP_OVERFLOW_CHECK */
00330 
00336 void
00337 memp_init(void)
00338 {
00339   struct memp *memp;
00340   u16_t i, j;
00341 
00342   for (i = 0; i < MEMP_MAX; ++i) {
00343     MEMP_STATS_AVAIL(used, i, 0);
00344     MEMP_STATS_AVAIL(max, i, 0);
00345     MEMP_STATS_AVAIL(err, i, 0);
00346     MEMP_STATS_AVAIL(avail, i, memp_num[i]);
00347   }
00348 
00349 #if !MEMP_SEPARATE_POOLS
00350   memp = (struct memp *)LWIP_MEM_ALIGN(memp_memory);
00351 #endif /* !MEMP_SEPARATE_POOLS */
00352   /* for every pool: */
00353   for (i = 0; i < MEMP_MAX; ++i) {
00354     memp_tab[i] = NULL;
00355 #if MEMP_SEPARATE_POOLS
00356     memp = (struct memp*)memp_bases[i];
00357 #endif /* MEMP_SEPARATE_POOLS */
00358     /* create a linked list of memp elements */
00359     for (j = 0; j < memp_num[i]; ++j) {
00360       memp->next = memp_tab[i];
00361       memp_tab[i] = memp;
00362       memp = (struct memp *)(void *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i]
00363 #if MEMP_OVERFLOW_CHECK
00364         + MEMP_SANITY_REGION_AFTER_ALIGNED
00365 #endif
00366       );
00367     }
00368   }
00369 #if MEMP_OVERFLOW_CHECK
00370   memp_overflow_init();
00371   /* check everything a first time to see if it worked */
00372   memp_overflow_check_all();
00373 #endif /* MEMP_OVERFLOW_CHECK */
00374 }
00375 
00387 void *
00388 #if !MEMP_OVERFLOW_CHECK
00389 memp_malloc(memp_t type)
00390 #else
00391 memp_malloc_fn(memp_t type, const char* file, const int line)
00392 #endif
00393 {
00394   struct memp *memp;
00395   SYS_ARCH_DECL_PROTECT(old_level);
00396  
00397   LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;);
00398 
00399   SYS_ARCH_PROTECT(old_level);
00400 #if MEMP_OVERFLOW_CHECK >= 2
00401   memp_overflow_check_all();
00402 #endif /* MEMP_OVERFLOW_CHECK >= 2 */
00403 
00404   memp = memp_tab[type];
00405   
00406   if (memp != NULL) {
00407     memp_tab[type] = memp->next;
00408 #if MEMP_OVERFLOW_CHECK
00409     memp->next = NULL;
00410     memp->file = file;
00411     memp->line = line;
00412 #endif /* MEMP_OVERFLOW_CHECK */
00413     MEMP_STATS_INC_USED(used, type);
00414     LWIP_ASSERT("memp_malloc: memp properly aligned",
00415                 ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0);
00416     memp = (struct memp*)(void *)((u8_t*)memp + MEMP_SIZE);
00417   } else {
00418     LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", memp_desc[type]));
00419     MEMP_STATS_INC(err, type);
00420   }
00421 
00422   SYS_ARCH_UNPROTECT(old_level);
00423 
00424   return memp;
00425 }
00426 
00433 void
00434 memp_free(memp_t type, void *mem)
00435 {
00436   struct memp *memp;
00437   SYS_ARCH_DECL_PROTECT(old_level);
00438 
00439   if (mem == NULL) {
00440     return;
00441   }
00442   LWIP_ASSERT("memp_free: mem properly aligned",
00443                 ((mem_ptr_t)mem % MEM_ALIGNMENT) == 0);
00444 
00445   memp = (struct memp *)(void *)((u8_t*)mem - MEMP_SIZE);
00446 
00447   SYS_ARCH_PROTECT(old_level);
00448 #if MEMP_OVERFLOW_CHECK
00449 #if MEMP_OVERFLOW_CHECK >= 2
00450   memp_overflow_check_all();
00451 #else
00452   memp_overflow_check_element_overflow(memp, type);
00453   memp_overflow_check_element_underflow(memp, type);
00454 #endif /* MEMP_OVERFLOW_CHECK >= 2 */
00455 #endif /* MEMP_OVERFLOW_CHECK */
00456 
00457   MEMP_STATS_DEC(used, type); 
00458   
00459   memp->next = memp_tab[type]; 
00460   memp_tab[type] = memp;
00461 
00462 #if MEMP_SANITY_CHECK
00463   LWIP_ASSERT("memp sanity", memp_sanity());
00464 #endif /* MEMP_SANITY_CHECK */
00465 
00466   SYS_ARCH_UNPROTECT(old_level);
00467 }
00468 
00469 #endif /* MEMP_MEM_MALLOC */

Generated on Fri May 25 2012 04:34:33 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.