From de9054cb7a7022f430c898bef29ec454b364b332 Mon Sep 17 00:00:00 2001 From: sg Date: Thu, 21 Jul 2016 22:17:32 +0200 Subject: [PATCH] memp: cleaned up MEMP_MEM_MALLOC: - support memp stats when MEMP_MEM_MALLOC==1 (bug #48442); - hide MEMP_MEM_MALLOC in memp.c instead of messing up the header file; - make MEMP_OVERFLOW_CHECK work when MEMP_MEM_MALLOC==1 --- CHANGELOG | 3 + src/apps/httpd/httpd.c | 75 ++++++---- src/core/memp.c | 241 +++++++++++++++++------------- src/include/lwip/memp.h | 23 +-- src/include/lwip/priv/memp_priv.h | 17 ++- src/include/lwip/priv/memp_std.h | 3 + 6 files changed, 208 insertions(+), 154 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 82e007f9..1451092f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -321,6 +321,9 @@ HISTORY ++ Bugfixes: + 2016-07-20: Simon Goldschmidt + * memp.h/.c: fixed bug #48442 (memp stats don't work for MEMP_MEM_MALLOC) + 2016-07-21: Simon Goldschmidt (patch by Ambroz Bizjak) * tcp_in.c, tcp_out.c: fixed bug #48543 (TCP sent callback may prematurely report sent data when only part of a segment is acked) and don't include diff --git a/src/apps/httpd/httpd.c b/src/apps/httpd/httpd.c index 8bed6a1c..3277b1bb 100644 --- a/src/apps/httpd/httpd.c +++ b/src/apps/httpd/httpd.c @@ -107,6 +107,8 @@ #if LWIP_HTTPD_SUPPORT_11_KEEPALIVE #define HTTP11_CONNECTIONKEEPALIVE "Connection: keep-alive" #define HTTP11_CONNECTIONKEEPALIVE2 "Connection: Keep-Alive" +#define HTTP11_CONNECTIONCLOSE "Connection: close" +#define HTTP11_CONNECTIONCLOSE2 "Connection: Close" #endif /** These defines check whether tcp_write has to copy data or not */ @@ -292,8 +294,8 @@ LWIP_MEMPOOL_DECLARE(HTTPD_SSI_STATE, MEMP_NUM_PARALLEL_HTTPD_SSI_CONNS, sizeof( static err_t http_close_conn(struct tcp_pcb *pcb, struct http_state *hs); static err_t http_close_or_abort_conn(struct tcp_pcb *pcb, struct http_state *hs, u8_t abort_conn); -static err_t http_find_file(struct http_state *hs, const char *uri, int is_09); -static err_t http_init_file(struct http_state *hs, struct fs_file *file, int is_09, const char *uri, u8_t tag_check, char* params); +static err_t http_find_file(struct http_state *hs, const char *uri, u8_t http_ver); +static err_t http_init_file(struct http_state *hs, struct fs_file *file, u8_t http_ver, const char *uri, u8_t tag_check, char* params); static err_t http_poll(void *arg, struct tcp_pcb *pcb); static u8_t http_check_eof(struct tcp_pcb *pcb, struct http_state *hs); #if LWIP_HTTPD_FS_ASYNC_READ @@ -895,13 +897,14 @@ get_tag_insert(struct http_state *hs) * them into the supplied buffer. */ static void -get_http_headers(struct http_state *hs, const char *uri) +get_http_headers(struct http_state *hs, const char *uri, u8_t http_ver) { size_t content_type; char *tmp; char *ext; char *vars; u8_t add_content_len; + int hdroffset11 = (http_ver >= 11) ? HTTP_HDR_OK_11 : 0; /* In all cases, the second header we send is the server identification so set it here. */ @@ -912,7 +915,7 @@ get_http_headers(struct http_state *hs, const char *uri) /* Is this a normal file or the special case we use to send back the default "404: Page not found" response? */ if (uri == NULL) { - hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_FOUND]; + hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_FOUND + hdroffset11]; #if LWIP_HTTPD_SUPPORT_11_KEEPALIVE if (hs->keepalive) { hs->hdrs[HDR_STRINGS_IDX_CONTENT_TYPE] = g_psHTTPHeaderStrings[DEFAULT_404_HTML_PERSISTENT]; @@ -932,13 +935,13 @@ get_http_headers(struct http_state *hs, const char *uri) indicative of a 404 server error whereas all other files require the 200 OK header. */ if (strstr(uri, "404")) { - hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_FOUND]; + hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_FOUND + hdroffset11]; } else if (strstr(uri, "400")) { - hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_BAD_REQUEST]; + hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_BAD_REQUEST + hdroffset11]; } else if (strstr(uri, "501")) { - hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_IMPL]; + hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_IMPL + hdroffset11]; } else { - hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_OK]; + hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_OK + hdroffset11]; } /* Determine if the URI has any variables and, if so, temporarily remove @@ -2021,7 +2024,7 @@ http_parse_request(struct pbuf *inp, struct http_state *hs, struct tcp_pcb *pcb) #if LWIP_HTTPD_SUPPORT_POST int is_post = 0; #endif /* LWIP_HTTPD_SUPPORT_POST */ - int is_09 = 0; + u8_t http_ver = 0; char *sp1, *sp2; u16_t left_len, uri_len; LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("CRLF received, parsing request\n")); @@ -2049,32 +2052,52 @@ http_parse_request(struct pbuf *inp, struct http_state *hs, struct tcp_pcb *pcb) /* if we come here, method is OK, parse URI */ left_len = (u16_t)(data_len - ((sp1 +1) - data)); sp2 = strnstr(sp1 + 1, " ", left_len); -#if LWIP_HTTPD_SUPPORT_V09 if (sp2 == NULL) { +#if LWIP_HTTPD_SUPPORT_V09 /* HTTP 0.9: respond with correct protocol version */ sp2 = strnstr(sp1 + 1, CRLF, left_len); - is_09 = 1; + http_ver = 9; #if LWIP_HTTPD_SUPPORT_POST if (is_post) { /* HTTP/0.9 does not support POST */ goto badrequest; } #endif /* LWIP_HTTPD_SUPPORT_POST */ - } #endif /* LWIP_HTTPD_SUPPORT_V09 */ + } else { + if (strstr(sp2, " HTTP/1.") == sp2) { + char ver = sp2[8]; + if ((ver >= '0') && (ver <= '9')) { + http_ver = 10 + (ver - '0'); + } + } + } uri_len = (u16_t)(sp2 - (sp1 + 1)); if ((sp2 != 0) && (sp2 > sp1)) { /* wait for CRLFCRLF (indicating end of HTTP headers) before parsing anything */ if (strnstr(data, CRLF CRLF, data_len) != NULL) { char *uri = sp1 + 1; #if LWIP_HTTPD_SUPPORT_11_KEEPALIVE - /* This is HTTP/1.0 compatible: for strict 1.1, a connection - would always be persistent unless "close" was specified. */ - if (!is_09 && (strnstr(data, HTTP11_CONNECTIONKEEPALIVE, data_len) || - strnstr(data, HTTP11_CONNECTIONKEEPALIVE2, data_len))) { - hs->keepalive = 1; - } else { +#if LWIP_HTTPD_SUPPORT_V09 + if (http_ver == 9) { hs->keepalive = 0; + } else +#endif /* LWIP_HTTPD_SUPPORT_V09 */ + /* If the "close" connection option is present, the connection will not persist after the current response */ + if (strnstr(data, HTTP11_CONNECTIONCLOSE, data_len) || + strnstr(data, HTTP11_CONNECTIONCLOSE2, data_len)) { + hs->keepalive = 0; + } else if (http_ver >= 11) { + /* If the received protocol is HTTP/1.1 (or later), the connection will persist after the current response */ + hs->keepalive = 1; + } else if (http_ver == 10) { + /* HTTP/1.1: keepalive supported when explicitly requested */ + if (strnstr(data, HTTP11_CONNECTIONKEEPALIVE, data_len) || + strnstr(data, HTTP11_CONNECTIONKEEPALIVE2, data_len)) { + hs->keepalive = 1; + } else { + hs->keepalive = 0; + } } #endif /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */ /* null-terminate the METHOD (pbuf is freed anyway wen returning) */ @@ -2103,7 +2126,7 @@ http_parse_request(struct pbuf *inp, struct http_state *hs, struct tcp_pcb *pcb) } else #endif /* LWIP_HTTPD_SUPPORT_POST */ { - return http_find_file(hs, uri, is_09); + return http_find_file(hs, uri, http_ver); } } } else { @@ -2135,12 +2158,12 @@ badrequest: * * @param hs the connection state * @param uri the HTTP header URI - * @param is_09 1 if the request is HTTP/0.9 (no HTTP headers in response) + * @param http_ver major/minor version of the HTTP request ((major*10)+minor) * @return ERR_OK if file was found and hs has been initialized correctly * another err_t otherwise */ static err_t -http_find_file(struct http_state *hs, const char *uri, int is_09) +http_find_file(struct http_state *hs, const char *uri, u8_t http_ver) { size_t loop; struct fs_file *file = NULL; @@ -2270,7 +2293,7 @@ http_find_file(struct http_state *hs, const char *uri, int is_09) /* None of the default filenames exist so send back a 404 page */ file = http_get_404_file(hs, &uri); } - return http_init_file(hs, file, is_09, uri, tag_check, params); + return http_init_file(hs, file, http_ver, uri, tag_check, params); } /** Initialize a http connection with a file to send (if found). @@ -2278,7 +2301,7 @@ http_find_file(struct http_state *hs, const char *uri, int is_09) * * @param hs http connection state * @param file file structure to send (or NULL if not found) - * @param is_09 1 if the request is HTTP/0.9 (no HTTP headers in response) + * @param http_ver major/minor version of the HTTP request ((major*10)+minor) * @param uri the HTTP header URI * @param tag_check enable SSI tag checking * @param uri_has_params != NULL if URI has parameters (separated by '?') @@ -2286,7 +2309,7 @@ http_find_file(struct http_state *hs, const char *uri, int is_09) * another err_t otherwise */ static err_t -http_init_file(struct http_state *hs, struct fs_file *file, int is_09, const char *uri, +http_init_file(struct http_state *hs, struct fs_file *file, u8_t http_ver, const char *uri, u8_t tag_check, char* params) { if (file != NULL) { @@ -2327,7 +2350,7 @@ http_init_file(struct http_state *hs, struct fs_file *file, int is_09, const cha (hs->handle->flags & FS_FILE_FLAGS_HEADER_INCLUDED) != 0); #endif /* !LWIP_HTTPD_DYNAMIC_HEADERS */ #if LWIP_HTTPD_SUPPORT_V09 - if (is_09 && ((hs->handle->flags & FS_FILE_FLAGS_HEADER_INCLUDED) != 0)) { + if ((http_ver == 9) && ((hs->handle->flags & FS_FILE_FLAGS_HEADER_INCLUDED) != 0)) { /* HTTP/0.9 responses are sent without HTTP header, search for the end of the header. */ char *file_start = strnstr(hs->file, CRLF CRLF, hs->left); @@ -2369,7 +2392,7 @@ http_init_file(struct http_state *hs, struct fs_file *file, int is_09, const cha /* Determine the HTTP headers to send based on the file extension of * the requested URI. */ if ((hs->handle == NULL) || ((hs->handle->flags & FS_FILE_FLAGS_HEADER_INCLUDED) == 0)) { - get_http_headers(hs, uri); + get_http_headers(hs, uri, http_ver); } #else /* LWIP_HTTPD_DYNAMIC_HEADERS */ LWIP_UNUSED_ARG(uri); diff --git a/src/core/memp.c b/src/core/memp.c index 73de1699..4aa1fbaf 100644 --- a/src/core/memp.c +++ b/src/core/memp.c @@ -41,33 +41,35 @@ #include "lwip/opt.h" #include "lwip/memp.h" +#include "lwip/sys.h" +#include "lwip/stats.h" + +#include + +/* Make sure we include everything we need for size calculation required by memp_std.h */ #include "lwip/pbuf.h" -#include "lwip/udp.h" #include "lwip/raw.h" -#include "lwip/igmp.h" +#include "lwip/udp.h" +#include "lwip/tcp.h" +#include "lwip/priv/tcp_priv.h" +#include "lwip/ip4_frag.h" +#include "lwip/netbuf.h" #include "lwip/api.h" +#include "lwip/priv/tcpip_priv.h" #include "lwip/priv/api_msg.h" #include "lwip/sockets.h" -#include "lwip/sys.h" -#include "lwip/timeouts.h" -#include "lwip/stats.h" +#include "lwip/netifapi.h" #include "lwip/etharp.h" -#include "lwip/ip4_frag.h" -#include "lwip/dns.h" +#include "lwip/igmp.h" +#include "lwip/timeouts.h" +/* needed by default MEMP_NUM_SYS_TIMEOUT */ +#include "netif/ppp/ppp_opts.h" #include "lwip/netdb.h" +#include "lwip/dns.h" #include "lwip/nd6.h" #include "lwip/ip6_frag.h" #include "lwip/mld6.h" -#include "lwip/tcp.h" -#include "lwip/tcpip.h" -#include "lwip/priv/tcp_priv.h" -#include "lwip/priv/tcpip_priv.h" -#include "lwip/netifapi.h" -/* needed by MEMP_NUM_SYS_TIMEOUT */ -#include "netif/ppp/ppp_opts.h" - -#include #define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEMPOOL_DECLARE(name,num,size,desc) #include "lwip/priv/memp_std.h" @@ -77,9 +79,13 @@ const struct memp_desc* const memp_pools[MEMP_MAX] = { #include "lwip/priv/memp_std.h" }; -#if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */ +#if MEMP_MEM_MALLOC && MEMP_OVERFLOW_CHECK >= 2 +#undef MEMP_OVERFLOW_CHECK +/* MEMP_OVERFLOW_CHECK >= 2 does not work with MEMP_MEM_MALLOC, use 1 instead */ +#define MEMP_OVERFLOW_CHECK 1 +#endif -#if MEMP_SANITY_CHECK +#if MEMP_SANITY_CHECK && !MEMP_MEM_MALLOC /** * Check that memp-lists don't form a circle, using "Floyd's cycle-finding algorithm". */ @@ -100,10 +106,9 @@ memp_sanity(const struct memp_desc *desc) return 1; } -#endif /* MEMP_SANITY_CHECK*/ +#endif /* MEMP_SANITY_CHECK && !MEMP_MEM_MALLOC */ #if MEMP_OVERFLOW_CHECK - /** * Check if a memp element was victim of an overflow * (e.g. the restricted area after it has been altered) @@ -152,6 +157,24 @@ memp_overflow_check_element_underflow(struct memp *p, const struct memp_desc *de #endif } +/** + * Initialize the restricted area of on memp element. + */ +static void +memp_overflow_init_element(struct memp *p, const struct memp_desc *desc) +{ + u8_t *m; +#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0 + m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED; + memset(m, 0xcd, MEMP_SANITY_REGION_BEFORE_ALIGNED); +#endif +#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0 + m = (u8_t*)p + MEMP_SIZE + desc->size; + memset(m, 0xcd, MEMP_SANITY_REGION_AFTER_ALIGNED); +#endif +} + +#if MEMP_OVERFLOW_CHECK >= 2 /** * Do an overflow check for all elements in every pool. * @@ -162,6 +185,8 @@ memp_overflow_check_all(void) { u16_t i, j; struct memp *p; + SYS_ARCH_DECL_PROTECT(old_level); + SYS_ARCH_PROTECT(old_level); for (i = 0; i < MEMP_MAX; ++i) { p = (struct memp *)(size_t)(memp_pools[i]->base); @@ -171,31 +196,27 @@ memp_overflow_check_all(void) p = (struct memp*)(size_t)((u8_t*)p + MEMP_SIZE + memp_pools[i]->size + MEMP_SANITY_REGION_AFTER_ALIGNED); } } + SYS_ARCH_UNPROTECT(old_level); } +#endif /* MEMP_OVERFLOW_CHECK >= 2 */ +#if !MEMP_MEM_MALLOC /** - * Initialize the restricted areas of all memp elements in every pool. + * Initialize the restricted areas of all memp elements in a pool. */ static void memp_overflow_init(const struct memp_desc *desc) { u16_t i; struct memp *p; - u8_t *m; p = (struct memp *)(size_t)(desc->base); for (i = 0; i < desc->num; ++i) { -#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0 - m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED; - memset(m, 0xcd, MEMP_SANITY_REGION_BEFORE_ALIGNED); -#endif -#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0 - m = (u8_t*)p + MEMP_SIZE + desc->size; - memset(m, 0xcd, MEMP_SANITY_REGION_AFTER_ALIGNED); -#endif + memp_overflow_init_element(p, desc); p = (struct memp*)(size_t)((u8_t*)p + MEMP_SIZE + desc->size + MEMP_SANITY_REGION_AFTER_ALIGNED); } } +#endif /* !MEMP_MEM_MALLOC */ #endif /* MEMP_OVERFLOW_CHECK */ /** @@ -207,9 +228,10 @@ memp_overflow_init(const struct memp_desc *desc) void memp_init_pool(const struct memp_desc *desc) { +#if !MEMP_MEM_MALLOC int i; struct memp *memp; - + *desc->tab = NULL; memp = (struct memp*)LWIP_MEM_ALIGN(desc->base); /* create a linked list of memp elements */ @@ -222,14 +244,17 @@ memp_init_pool(const struct memp_desc *desc) + MEMP_SANITY_REGION_AFTER_ALIGNED #endif ); - } + } #if MEMP_OVERFLOW_CHECK memp_overflow_init(desc); #endif /* MEMP_OVERFLOW_CHECK */ +#endif /* !MEMP_MEM_MALLOC */ #if MEMP_STATS +#if !MEMP_MEM_MALLOC desc->stats->avail = desc->num; +#endif /* !MEMP_MEM_MALLOC */ #if defined(LWIP_DEBUG) || LWIP_STATS_DISPLAY desc->stats->name = desc->desc; @@ -257,12 +282,71 @@ memp_init(void) #endif } -#if MEMP_OVERFLOW_CHECK +#if MEMP_OVERFLOW_CHECK >= 2 /* check everything a first time to see if it worked */ memp_overflow_check_all(); -#endif /* MEMP_OVERFLOW_CHECK */ +#endif /* MEMP_OVERFLOW_CHECK >= 2 */ } +static void* +#if !MEMP_OVERFLOW_CHECK +do_memp_malloc_pool(const struct memp_desc *desc) +#else +do_memp_malloc_pool_fn(const struct memp_desc *desc, const char* file, const int line) +#endif +{ + struct memp *memp; + SYS_ARCH_DECL_PROTECT(old_level); + +#if MEMP_MEM_MALLOC + memp = (struct memp *)mem_malloc(MEMP_SIZE + MEMP_ALIGN_SIZE(desc->size)); + SYS_ARCH_PROTECT(old_level); +#else /* MEMP_MEM_MALLOC */ + SYS_ARCH_PROTECT(old_level); + + memp = *desc->tab; + +#if MEMP_OVERFLOW_CHECK == 1 + memp_overflow_check_element_overflow(memp, desc); + memp_overflow_check_element_underflow(memp, desc); +#endif /* MEMP_OVERFLOW_CHECK */ +#endif /* MEMP_MEM_MALLOC */ + + if (memp != NULL) { +#if !MEMP_MEM_MALLOC + *desc->tab = memp->next; +#if MEMP_OVERFLOW_CHECK + memp->next = NULL; +#endif /* MEMP_OVERFLOW_CHECK */ +#endif /* !MEMP_MEM_MALLOC */ +#if MEMP_OVERFLOW_CHECK + memp->file = file; + memp->line = line; +#if MEMP_MEM_MALLOC + memp_overflow_init_element(memp, desc); +#endif /* MEMP_MEM_MALLOC */ +#endif /* MEMP_OVERFLOW_CHECK */ + LWIP_ASSERT("memp_malloc: memp properly aligned", + ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0); +#if MEMP_STATS + desc->stats->used++; + if (desc->stats->used > desc->stats->max) { + desc->stats->max = desc->stats->used; + } +#endif + SYS_ARCH_UNPROTECT(old_level); + /* cast through u8_t* to get rid of alignment warnings */ + return ((u8_t*)memp + MEMP_SIZE); + } else { + LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", desc->desc)); +#if MEMP_STATS + desc->stats->err++; +#endif + } + + SYS_ARCH_UNPROTECT(old_level); + return NULL; +} /** * Get an element from a custom pool. @@ -282,48 +366,16 @@ memp_malloc_pool(const struct memp_desc *desc) memp_malloc_pool_fn(const struct memp_desc *desc, const char* file, const int line) #endif { - struct memp *memp; - SYS_ARCH_DECL_PROTECT(old_level); - - SYS_ARCH_PROTECT(old_level); - - memp = *desc->tab; - -#if MEMP_OVERFLOW_CHECK == 1 - memp_overflow_check_element_overflow(memp, desc); - memp_overflow_check_element_underflow(memp, desc); -#endif /* MEMP_OVERFLOW_CHECK */ - - if (memp != NULL) { - *desc->tab = memp->next; -#if MEMP_OVERFLOW_CHECK - memp->next = NULL; - memp->file = file; - memp->line = line; -#endif /* MEMP_OVERFLOW_CHECK */ - LWIP_ASSERT("memp_malloc: memp properly aligned", - ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0); - /* cast through void* to get rid of alignment warnings */ - memp = (struct memp*)(void *)((u8_t*)memp + MEMP_SIZE); + LWIP_ASSERT("invalid pool desc", desc != NULL); + if (desc == NULL) { + return NULL; } - if (memp != NULL) { -#if MEMP_STATS - desc->stats->used++; - if (desc->stats->used > desc->stats->max) { - desc->stats->max = desc->stats->used; - } +#if !MEMP_OVERFLOW_CHECK + return memp_malloc_pool(desc); +#else + return memp_malloc_pool_fn(desc, file, line); #endif - } else { - LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", desc->desc)); -#if MEMP_STATS - desc->stats->err++; -#endif - } - - SYS_ARCH_UNPROTECT(old_level); - - return memp; } /** @@ -345,36 +397,26 @@ memp_malloc_fn(memp_t type, const char* file, const int line) #endif { void *memp; - SYS_ARCH_DECL_PROTECT(old_level); - LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;); - SYS_ARCH_PROTECT(old_level); - #if MEMP_OVERFLOW_CHECK >= 2 memp_overflow_check_all(); #endif /* MEMP_OVERFLOW_CHECK >= 2 */ #if !MEMP_OVERFLOW_CHECK - memp = memp_malloc_pool(memp_pools[type]); + memp = do_memp_malloc_pool(memp_pools[type]); #else - memp = memp_malloc_pool_fn(memp_pools[type], file, line); + memp = do_memp_malloc_pool_fn(memp_pools[type], file, line); #endif - SYS_ARCH_UNPROTECT(old_level); - return memp; } static void -#ifdef LWIP_HOOK_MEMP_AVAILABLE -do_memp_free_pool(const struct memp_desc* desc, void *mem, struct memp **old_first) -#else do_memp_free_pool(const struct memp_desc* desc, void *mem) -#endif { - struct memp *memp; SYS_ARCH_DECL_PROTECT(old_level); + struct memp *memp; LWIP_ASSERT("memp_free: mem properly aligned", ((mem_ptr_t)mem % MEM_ALIGNMENT) == 0); @@ -393,13 +435,11 @@ do_memp_free_pool(const struct memp_desc* desc, void *mem) desc->stats->used--; #endif +#if MEMP_MEM_MALLOC + SYS_ARCH_UNPROTECT(old_level); + mem_free(memp); +#else /* MEMP_MEM_MALLOC */ memp->next = *desc->tab; - -#ifdef LWIP_HOOK_MEMP_AVAILABLE - if (old_first) - *old_first = *desc->tab; -#endif - *desc->tab = memp; #if MEMP_SANITY_CHECK @@ -407,6 +447,7 @@ do_memp_free_pool(const struct memp_desc* desc, void *mem) #endif /* MEMP_SANITY_CHECK */ SYS_ARCH_UNPROTECT(old_level); +#endif /* !MEMP_MEM_MALLOC */ } /** @@ -418,15 +459,12 @@ do_memp_free_pool(const struct memp_desc* desc, void *mem) void memp_free_pool(const struct memp_desc* desc, void *mem) { + LWIP_ASSERT("invalid pool desc", desc != NULL); if ((desc == NULL) || (mem == NULL)) { return; } -#ifdef LWIP_HOOK_MEMP_AVAILABLE - do_memp_free_pool(desc, mem, NULL); -#else do_memp_free_pool(desc, mem); -#endif } /** @@ -441,23 +479,18 @@ memp_free(memp_t type, void *mem) #ifdef LWIP_HOOK_MEMP_AVAILABLE struct memp *old_first; #endif - SYS_ARCH_DECL_PROTECT(old_level); LWIP_ERROR("memp_free: type < MEMP_MAX", (type < MEMP_MAX), return;); - SYS_ARCH_PROTECT(old_level); - #if MEMP_OVERFLOW_CHECK >= 2 memp_overflow_check_all(); #endif /* MEMP_OVERFLOW_CHECK >= 2 */ #ifdef LWIP_HOOK_MEMP_AVAILABLE - do_memp_free_pool(memp_pools[type], mem, &old_first); -#else - do_memp_free_pool(memp_pools[type], mem); + old_first = memp_pools[type].tab; #endif - SYS_ARCH_UNPROTECT(old_level); + do_memp_free_pool(memp_pools[type], mem); #ifdef LWIP_HOOK_MEMP_AVAILABLE if (old_first == NULL) { @@ -465,5 +498,3 @@ memp_free(memp_t type, void *mem) } #endif } - -#endif /* MEMP_MEM_MALLOC */ diff --git a/src/include/lwip/memp.h b/src/include/lwip/memp.h index 35ac8d51..59468495 100644 --- a/src/include/lwip/memp.h +++ b/src/include/lwip/memp.h @@ -60,21 +60,14 @@ extern const struct memp_desc* const memp_pools[MEMP_MAX]; #if MEMP_MEM_MALLOC -#include "lwip/mem.h" - -#define memp_init() -#define memp_malloc(type) mem_malloc(memp_pools[type]->size) -#define memp_free(type, mem) mem_free(mem) - #define LWIP_MEMPOOL_DECLARE(name,num,size,desc) \ + LWIP_MEMPOOL_DECLARE_STATS_INSTANCE(memp_stats_ ## name) \ const struct memp_desc memp_ ## name = { \ + DECLARE_LWIP_MEMPOOL_DESC(desc) \ + LWIP_MEMPOOL_DECLARE_STATS_REFERENCE(memp_stats_ ## name) \ LWIP_MEM_ALIGN_SIZE(size) \ }; -#define LWIP_MEMPOOL_INIT(name) -#define LWIP_MEMPOOL_ALLOC(name) mem_malloc(memp_ ## name.size) -#define LWIP_MEMPOOL_FREE(name, x) mem_free(x) - #else /* MEMP_MEM_MALLOC */ /** Declare a private memory pool @@ -102,14 +95,16 @@ extern const struct memp_desc* const memp_pools[MEMP_MAX]; static struct memp *memp_tab_ ## name; \ \ const struct memp_desc memp_ ## name = { \ - LWIP_MEM_ALIGN_SIZE(size), \ - LWIP_MEMPOOL_DECLARE_STATS_REFERENCE(memp_stats_ ## name) \ - (num), \ DECLARE_LWIP_MEMPOOL_DESC(desc) \ + LWIP_MEMPOOL_DECLARE_STATS_REFERENCE(memp_stats_ ## name) \ + LWIP_MEM_ALIGN_SIZE(size), \ + (num), \ memp_memory_ ## name ## _base, \ &memp_tab_ ## name \ }; +#endif /* MEMP_MEM_MALLOC */ + /** Initialize a private memory pool */ #define LWIP_MEMPOOL_INIT(name) memp_init_pool(&memp_ ## name) /** Allocate from a private memory pool */ @@ -139,8 +134,6 @@ void *memp_malloc(memp_t type); #endif void memp_free(memp_t type, void *mem); -#endif /* MEMP_MEM_MALLOC */ - #ifdef __cplusplus } #endif diff --git a/src/include/lwip/priv/memp_priv.h b/src/include/lwip/priv/memp_priv.h index 4b958f95..242b6d19 100644 --- a/src/include/lwip/priv/memp_priv.h +++ b/src/include/lwip/priv/memp_priv.h @@ -87,6 +87,7 @@ extern "C" { #endif /* MEMP_OVERFLOW_CHECK */ +#if !MEMP_MEM_MALLOC || MEMP_OVERFLOW_CHECK struct memp { struct memp *next; #if MEMP_OVERFLOW_CHECK @@ -94,6 +95,7 @@ struct memp { int line; #endif /* MEMP_OVERFLOW_CHECK */ }; +#endif /* !MEMP_MEM_MALLOC || MEMP_OVERFLOW_CHECK */ #if MEM_USE_POOLS /* Use a helper type to get the start and end of the user "memory pools" for mem_malloc */ @@ -126,23 +128,22 @@ typedef enum { /** Memory pool descriptor */ struct memp_desc { - /** Element size */ - u16_t size; - +#if defined(LWIP_DEBUG) || MEMP_OVERFLOW_CHECK || LWIP_STATS_DISPLAY + /** Textual description */ + const char *desc; +#endif /* LWIP_DEBUG || MEMP_OVERFLOW_CHECK || LWIP_STATS_DISPLAY */ #if MEMP_STATS /** Statistics */ struct stats_mem *stats; #endif + /** Element size */ + u16_t size; + #if !MEMP_MEM_MALLOC /** Number of elements */ u16_t num; -#if defined(LWIP_DEBUG) || MEMP_OVERFLOW_CHECK || LWIP_STATS_DISPLAY - /** Textual description */ - const char *desc; -#endif /* LWIP_DEBUG || MEMP_OVERFLOW_CHECK || LWIP_STATS_DISPLAY */ - /** Base address */ u8_t *base; diff --git a/src/include/lwip/priv/memp_std.h b/src/include/lwip/priv/memp_std.h index 44e15662..59f436df 100644 --- a/src/include/lwip/priv/memp_std.h +++ b/src/include/lwip/priv/memp_std.h @@ -1,6 +1,9 @@ /** * @file * lwIP internal memory pools (do not use in application code) + * This file is deliberately included multiple times: once with empty + * definition of LWIP_MEMPOOL() to handle all includes and multiple times + * to build up various lists of mem pools. */ /*