mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-03-20 19:21:05 +00:00
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
This commit is contained in:
parent
413eeef5fa
commit
de9054cb7a
@ -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
|
||||
|
@ -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);
|
||||
|
241
src/core/memp.c
241
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 <string.h>
|
||||
|
||||
/* 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 <string.h>
|
||||
|
||||
#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 */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user