Warning, cross-references for /kernel/lwip/core/memp.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 #include "lwip/opt.h"
0042
0043 #include "lwip/memp.h"
0044 #include "lwip/pbuf.h"
0045 #include "lwip/udp.h"
0046 #include "lwip/raw.h"
0047 #include "lwip/tcp.h"
0048 #include "lwip/igmp.h"
0049 #include "lwip/api.h"
0050 #include "lwip/api_msg.h"
0051 #include "lwip/tcpip.h"
0052 #include "lwip/sys.h"
0053 #include "lwip/stats.h"
0054 #include "netif/etharp.h"
0055 #include "lwip/ip_frag.h"
0056
0057 #include <string.h>
0058
0059 #if !MEMP_MEM_MALLOC
0060
0061 struct memp {
0062 struct memp *next;
0063 #if MEMP_OVERFLOW_CHECK
0064 const char *file;
0065 int line;
0066 #endif
0067 };
0068
0069 #if MEMP_OVERFLOW_CHECK
0070
0071
0072
0073
0074
0075
0076
0077
0078 #ifndef MEMP_SANITY_REGION_BEFORE
0079 #define MEMP_SANITY_REGION_BEFORE 16
0080 #endif
0081 #if MEMP_SANITY_REGION_BEFORE > 0
0082 #define MEMP_SANITY_REGION_BEFORE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_BEFORE)
0083 #else
0084 #define MEMP_SANITY_REGION_BEFORE_ALIGNED 0
0085 #endif
0086 #ifndef MEMP_SANITY_REGION_AFTER
0087 #define MEMP_SANITY_REGION_AFTER 16
0088 #endif
0089 #if MEMP_SANITY_REGION_AFTER > 0
0090 #define MEMP_SANITY_REGION_AFTER_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_AFTER)
0091 #else
0092 #define MEMP_SANITY_REGION_AFTER_ALIGNED 0
0093 #endif
0094
0095
0096 #define MEMP_SIZE (LWIP_MEM_ALIGN_SIZE(sizeof(struct memp)) + MEMP_SANITY_REGION_BEFORE_ALIGNED)
0097 #define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x) + MEMP_SANITY_REGION_AFTER_ALIGNED)
0098
0099 #else
0100
0101
0102
0103
0104
0105 #define MEMP_SIZE 0
0106 #define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x))
0107
0108 #endif
0109
0110
0111
0112 static struct memp *memp_tab[MEMP_MAX];
0113
0114 #else
0115
0116 #define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x))
0117
0118 #endif
0119
0120
0121 #if !MEM_USE_POOLS && !MEMP_MEM_MALLOC
0122 static
0123 #endif
0124 const u16_t memp_sizes[MEMP_MAX] = {
0125 #define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEM_ALIGN_SIZE(size),
0126 #include "lwip/memp_std.h"
0127 };
0128
0129 #if !MEMP_MEM_MALLOC
0130
0131
0132 static const u16_t memp_num[MEMP_MAX] = {
0133 #define LWIP_MEMPOOL(name,num,size,desc) (num),
0134 #include "lwip/memp_std.h"
0135 };
0136
0137
0138 #ifdef LWIP_DEBUG
0139 static const char *memp_desc[MEMP_MAX] = {
0140 #define LWIP_MEMPOOL(name,num,size,desc) (desc),
0141 #include "lwip/memp_std.h"
0142 };
0143 #endif
0144
0145
0146 static u8_t memp_memory[MEM_ALIGNMENT - 1
0147 #define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) )
0148 #include "lwip/memp_std.h"
0149 ];
0150
0151 #if MEMP_SANITY_CHECK
0152
0153
0154
0155 static int
0156 memp_sanity(void)
0157 {
0158 s16_t i, c;
0159 struct memp *m, *n;
0160
0161 for (i = 0; i < MEMP_MAX; i++) {
0162 for (m = memp_tab[i]; m != NULL; m = m->next) {
0163 c = 1;
0164 for (n = memp_tab[i]; n != NULL; n = n->next) {
0165 if (n == m && --c < 0) {
0166 return 0;
0167 }
0168 }
0169 }
0170 }
0171 return 1;
0172 }
0173 #endif
0174 #if MEMP_OVERFLOW_CHECK
0175
0176
0177
0178
0179
0180
0181
0182 static void
0183 memp_overflow_check_element(struct memp *p, u16_t memp_size)
0184 {
0185 u16_t k;
0186 u8_t *m;
0187 #if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0
0188 m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED;
0189 for (k = 0; k < MEMP_SANITY_REGION_BEFORE_ALIGNED; k++) {
0190 if (m[k] != 0xcd) {
0191 LWIP_ASSERT("detected memp underflow!", 0);
0192 }
0193 }
0194 #endif
0195 #if MEMP_SANITY_REGION_AFTER_ALIGNED > 0
0196 m = (u8_t*)p + MEMP_SIZE + memp_size;
0197 for (k = 0; k < MEMP_SANITY_REGION_AFTER_ALIGNED; k++) {
0198 if (m[k] != 0xcd) {
0199 LWIP_ASSERT("detected memp overflow!", 0);
0200 }
0201 }
0202 #endif
0203 }
0204
0205
0206
0207
0208
0209
0210 static void
0211 memp_overflow_check_all(void)
0212 {
0213 u16_t i, j;
0214 struct memp *p;
0215
0216 p = LWIP_MEM_ALIGN(memp_memory);
0217 for (i = 0; i < MEMP_MAX; ++i) {
0218 p = p;
0219 for (j = 0; j < memp_num[i]; ++j) {
0220 memp_overflow_check_element(p, memp_sizes[i]);
0221 p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED);
0222 }
0223 }
0224 }
0225
0226
0227
0228
0229 static void
0230 memp_overflow_init(void)
0231 {
0232 u16_t i, j;
0233 struct memp *p;
0234 u8_t *m;
0235
0236 p = LWIP_MEM_ALIGN(memp_memory);
0237 for (i = 0; i < MEMP_MAX; ++i) {
0238 p = p;
0239 for (j = 0; j < memp_num[i]; ++j) {
0240 #if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0
0241 m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED;
0242 memset(m, 0xcd, MEMP_SANITY_REGION_BEFORE_ALIGNED);
0243 #endif
0244 #if MEMP_SANITY_REGION_AFTER_ALIGNED > 0
0245 m = (u8_t*)p + MEMP_SIZE + memp_sizes[i];
0246 memset(m, 0xcd, MEMP_SANITY_REGION_AFTER_ALIGNED);
0247 #endif
0248 p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED);
0249 }
0250 }
0251 }
0252 #endif
0253
0254
0255
0256
0257
0258
0259 void
0260 memp_init(void)
0261 {
0262 struct memp *memp;
0263 u16_t i, j;
0264
0265 for (i = 0; i < MEMP_MAX; ++i) {
0266 MEMP_STATS_AVAIL(used, i, 0);
0267 MEMP_STATS_AVAIL(max, i, 0);
0268 MEMP_STATS_AVAIL(err, i, 0);
0269 MEMP_STATS_AVAIL(avail, i, memp_num[i]);
0270 }
0271
0272 memp = LWIP_MEM_ALIGN(memp_memory);
0273
0274 for (i = 0; i < MEMP_MAX; ++i) {
0275 memp_tab[i] = NULL;
0276
0277 for (j = 0; j < memp_num[i]; ++j) {
0278 memp->next = memp_tab[i];
0279 memp_tab[i] = memp;
0280 memp = (struct memp *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i]
0281 #if MEMP_OVERFLOW_CHECK
0282 + MEMP_SANITY_REGION_AFTER_ALIGNED
0283 #endif
0284 );
0285 }
0286 }
0287 #if MEMP_OVERFLOW_CHECK
0288 memp_overflow_init();
0289
0290 memp_overflow_check_all();
0291 #endif
0292 }
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305 void *
0306 #if !MEMP_OVERFLOW_CHECK
0307 memp_malloc(memp_t type)
0308 #else
0309 memp_malloc_fn(memp_t type, const char* file, const int line)
0310 #endif
0311 {
0312 struct memp *memp;
0313 SYS_ARCH_DECL_PROTECT(old_level);
0314
0315 LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;);
0316
0317 SYS_ARCH_PROTECT(old_level);
0318 #if MEMP_OVERFLOW_CHECK >= 2
0319 memp_overflow_check_all();
0320 #endif
0321
0322 memp = memp_tab[type];
0323
0324 if (memp != NULL) {
0325 memp_tab[type] = memp->next;
0326 #if MEMP_OVERFLOW_CHECK
0327 memp->next = NULL;
0328 memp->file = file;
0329 memp->line = line;
0330 #endif
0331 MEMP_STATS_INC_USED(used, type);
0332 LWIP_ASSERT("memp_malloc: memp properly aligned",
0333 ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0);
0334 memp = (struct memp*)((u8_t*)memp + MEMP_SIZE);
0335 } else {
0336 LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", memp_desc[type]));
0337 MEMP_STATS_INC(err, type);
0338 }
0339
0340 SYS_ARCH_UNPROTECT(old_level);
0341
0342 return memp;
0343 }
0344
0345
0346
0347
0348
0349
0350
0351 void
0352 memp_free(memp_t type, void *mem)
0353 {
0354 struct memp *memp;
0355 SYS_ARCH_DECL_PROTECT(old_level);
0356
0357 if (mem == NULL) {
0358 return;
0359 }
0360 LWIP_ASSERT("memp_free: mem properly aligned",
0361 ((mem_ptr_t)mem % MEM_ALIGNMENT) == 0);
0362
0363 memp = (struct memp *)((u8_t*)mem - MEMP_SIZE);
0364
0365 SYS_ARCH_PROTECT(old_level);
0366 #if MEMP_OVERFLOW_CHECK
0367 #if MEMP_OVERFLOW_CHECK >= 2
0368 memp_overflow_check_all();
0369 #else
0370 memp_overflow_check_element(memp, memp_sizes[type]);
0371 #endif
0372 #endif
0373
0374 MEMP_STATS_DEC(used, type);
0375
0376 memp->next = memp_tab[type];
0377 memp_tab[type] = memp;
0378
0379 #if MEMP_SANITY_CHECK
0380 LWIP_ASSERT("memp sanity", memp_sanity());
0381 #endif
0382
0383 SYS_ARCH_UNPROTECT(old_level);
0384 }
0385
0386 #endif