00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
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.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/stats.h"
00054 #include "netif/etharp.h"
00055 #include "lwip/ip_frag.h"
00056
00057 #include <string.h>
00058
00059 #if !MEMP_MEM_MALLOC
00060
00061 struct memp {
00062 struct memp *next;
00063 #if MEMP_OVERFLOW_CHECK
00064 const char *file;
00065 int line;
00066 #endif
00067 };
00068
00069 #if MEMP_OVERFLOW_CHECK
00070
00071
00072
00073
00074
00075
00076
00077
00078 #ifndef MEMP_SANITY_REGION_BEFORE
00079 #define MEMP_SANITY_REGION_BEFORE 16
00080 #endif
00081 #if MEMP_SANITY_REGION_BEFORE > 0
00082 #define MEMP_SANITY_REGION_BEFORE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_BEFORE)
00083 #else
00084 #define MEMP_SANITY_REGION_BEFORE_ALIGNED 0
00085 #endif
00086 #ifndef MEMP_SANITY_REGION_AFTER
00087 #define MEMP_SANITY_REGION_AFTER 16
00088 #endif
00089 #if MEMP_SANITY_REGION_AFTER > 0
00090 #define MEMP_SANITY_REGION_AFTER_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_AFTER)
00091 #else
00092 #define MEMP_SANITY_REGION_AFTER_ALIGNED 0
00093 #endif
00094
00095
00096 #define MEMP_SIZE (LWIP_MEM_ALIGN_SIZE(sizeof(struct memp)) + MEMP_SANITY_REGION_BEFORE_ALIGNED)
00097 #define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x) + MEMP_SANITY_REGION_AFTER_ALIGNED)
00098
00099 #else
00100
00101
00102
00103
00104
00105 #define MEMP_SIZE 0
00106 #define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x))
00107
00108 #endif
00109
00110
00111
00112 static struct memp *memp_tab[MEMP_MAX];
00113
00114 #else
00115
00116 #define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x))
00117
00118 #endif
00119
00120
00121 #if !MEM_USE_POOLS && !MEMP_MEM_MALLOC
00122 static
00123 #endif
00124 const u16_t memp_sizes[MEMP_MAX] = {
00125 #define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEM_ALIGN_SIZE(size),
00126 #include "lwip/memp_std.h"
00127 };
00128
00129 #if !MEMP_MEM_MALLOC
00130
00131
00132 static const u16_t memp_num[MEMP_MAX] = {
00133 #define LWIP_MEMPOOL(name,num,size,desc) (num),
00134 #include "lwip/memp_std.h"
00135 };
00136
00137
00138 #ifdef LWIP_DEBUG
00139 static const char *memp_desc[MEMP_MAX] = {
00140 #define LWIP_MEMPOOL(name,num,size,desc) (desc),
00141 #include "lwip/memp_std.h"
00142 };
00143 #endif
00144
00145
00146 static u8_t memp_memory[MEM_ALIGNMENT - 1
00147 #define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) )
00148 #include "lwip/memp_std.h"
00149 ];
00150
00151 #if MEMP_SANITY_CHECK
00152
00153
00154
00155 static int
00156 memp_sanity(void)
00157 {
00158 s16_t i, c;
00159 struct memp *m, *n;
00160
00161 for (i = 0; i < MEMP_MAX; i++) {
00162 for (m = memp_tab[i]; m != NULL; m = m->next) {
00163 c = 1;
00164 for (n = memp_tab[i]; n != NULL; n = n->next) {
00165 if (n == m && --c < 0) {
00166 return 0;
00167 }
00168 }
00169 }
00170 }
00171 return 1;
00172 }
00173 #endif
00174 #if MEMP_OVERFLOW_CHECK
00175
00176
00177
00178
00179
00180
00181
00182 static void
00183 memp_overflow_check_element(struct memp *p, u16_t memp_size)
00184 {
00185 u16_t k;
00186 u8_t *m;
00187 #if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0
00188 m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED;
00189 for (k = 0; k < MEMP_SANITY_REGION_BEFORE_ALIGNED; k++) {
00190 if (m[k] != 0xcd) {
00191 LWIP_ASSERT("detected memp underflow!", 0);
00192 }
00193 }
00194 #endif
00195 #if MEMP_SANITY_REGION_AFTER_ALIGNED > 0
00196 m = (u8_t*)p + MEMP_SIZE + memp_size;
00197 for (k = 0; k < MEMP_SANITY_REGION_AFTER_ALIGNED; k++) {
00198 if (m[k] != 0xcd) {
00199 LWIP_ASSERT("detected memp overflow!", 0);
00200 }
00201 }
00202 #endif
00203 }
00204
00205
00206
00207
00208
00209
00210 static void
00211 memp_overflow_check_all(void)
00212 {
00213 u16_t i, j;
00214 struct memp *p;
00215
00216 p = LWIP_MEM_ALIGN(memp_memory);
00217 for (i = 0; i < MEMP_MAX; ++i) {
00218 p = p;
00219 for (j = 0; j < memp_num[i]; ++j) {
00220 memp_overflow_check_element(p, memp_sizes[i]);
00221 p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED);
00222 }
00223 }
00224 }
00225
00226
00227
00228
00229 static void
00230 memp_overflow_init(void)
00231 {
00232 u16_t i, j;
00233 struct memp *p;
00234 u8_t *m;
00235
00236 p = LWIP_MEM_ALIGN(memp_memory);
00237 for (i = 0; i < MEMP_MAX; ++i) {
00238 p = p;
00239 for (j = 0; j < memp_num[i]; ++j) {
00240 #if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0
00241 m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED;
00242 memset(m, 0xcd, MEMP_SANITY_REGION_BEFORE_ALIGNED);
00243 #endif
00244 #if MEMP_SANITY_REGION_AFTER_ALIGNED > 0
00245 m = (u8_t*)p + MEMP_SIZE + memp_sizes[i];
00246 memset(m, 0xcd, MEMP_SANITY_REGION_AFTER_ALIGNED);
00247 #endif
00248 p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED);
00249 }
00250 }
00251 }
00252 #endif
00253
00254
00255
00256
00257
00258
00259 void
00260 memp_init(void)
00261 {
00262 struct memp *memp;
00263 u16_t i, j;
00264
00265 for (i = 0; i < MEMP_MAX; ++i) {
00266 MEMP_STATS_AVAIL(used, i, 0);
00267 MEMP_STATS_AVAIL(max, i, 0);
00268 MEMP_STATS_AVAIL(err, i, 0);
00269 MEMP_STATS_AVAIL(avail, i, memp_num[i]);
00270 }
00271
00272 memp = LWIP_MEM_ALIGN(memp_memory);
00273
00274 for (i = 0; i < MEMP_MAX; ++i) {
00275 memp_tab[i] = NULL;
00276
00277 for (j = 0; j < memp_num[i]; ++j) {
00278 memp->next = memp_tab[i];
00279 memp_tab[i] = memp;
00280 memp = (struct memp *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i]
00281 #if MEMP_OVERFLOW_CHECK
00282 + MEMP_SANITY_REGION_AFTER_ALIGNED
00283 #endif
00284 );
00285 }
00286 }
00287 #if MEMP_OVERFLOW_CHECK
00288 memp_overflow_init();
00289
00290 memp_overflow_check_all();
00291 #endif
00292 }
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 void *
00306 #if !MEMP_OVERFLOW_CHECK
00307 memp_malloc(memp_t type)
00308 #else
00309 memp_malloc_fn(memp_t type, const char* file, const int line)
00310 #endif
00311 {
00312 struct memp *memp;
00313 SYS_ARCH_DECL_PROTECT(old_level);
00314
00315 LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;);
00316
00317 SYS_ARCH_PROTECT(old_level);
00318 #if MEMP_OVERFLOW_CHECK >= 2
00319 memp_overflow_check_all();
00320 #endif
00321
00322 memp = memp_tab[type];
00323
00324 if (memp != NULL) {
00325 memp_tab[type] = memp->next;
00326 #if MEMP_OVERFLOW_CHECK
00327 memp->next = NULL;
00328 memp->file = file;
00329 memp->line = line;
00330 #endif
00331 MEMP_STATS_INC_USED(used, type);
00332 LWIP_ASSERT("memp_malloc: memp properly aligned",
00333 ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0);
00334 memp = (struct memp*)((u8_t*)memp + MEMP_SIZE);
00335 } else {
00336 LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", memp_desc[type]));
00337 MEMP_STATS_INC(err, type);
00338 }
00339
00340 SYS_ARCH_UNPROTECT(old_level);
00341
00342 return memp;
00343 }
00344
00345
00346
00347
00348
00349
00350
00351 void
00352 memp_free(memp_t type, void *mem)
00353 {
00354 struct memp *memp;
00355 SYS_ARCH_DECL_PROTECT(old_level);
00356
00357 if (mem == NULL) {
00358 return;
00359 }
00360 LWIP_ASSERT("memp_free: mem properly aligned",
00361 ((mem_ptr_t)mem % MEM_ALIGNMENT) == 0);
00362
00363 memp = (struct memp *)((u8_t*)mem - MEMP_SIZE);
00364
00365 SYS_ARCH_PROTECT(old_level);
00366 #if MEMP_OVERFLOW_CHECK
00367 #if MEMP_OVERFLOW_CHECK >= 2
00368 memp_overflow_check_all();
00369 #else
00370 memp_overflow_check_element(memp, memp_sizes[type]);
00371 #endif
00372 #endif
00373
00374 MEMP_STATS_DEC(used, type);
00375
00376 memp->next = memp_tab[type];
00377 memp_tab[type] = memp;
00378
00379 #if MEMP_SANITY_CHECK
00380 LWIP_ASSERT("memp sanity", memp_sanity());
00381 #endif
00382
00383 SYS_ARCH_UNPROTECT(old_level);
00384 }
00385
00386 #endif