From 49414826afee624113ed37bd84cc5e8f5c477145 Mon Sep 17 00:00:00 2001 From: goldsimon Date: Mon, 6 Mar 2017 21:53:48 +0100 Subject: [PATCH] pbuf: added new function pbuf_free_header() to gradually hide bytes and free pbufs from the front of a pbuf chain --- src/core/pbuf.c | 30 ++++++++++++++++++++++++++++++ src/include/lwip/pbuf.h | 1 + 2 files changed, 31 insertions(+) diff --git a/src/core/pbuf.c b/src/core/pbuf.c index 4dd1a26a..635f2f35 100644 --- a/src/core/pbuf.c +++ b/src/core/pbuf.c @@ -683,6 +683,36 @@ pbuf_header_force(struct pbuf *p, s16_t header_size_increment) return pbuf_header_impl(p, header_size_increment, 1); } +/** Similar to pbuf_header(-size) but de-refs header pbufs for (size >= p->len) + * + * @param q pbufs to operate on + * @param size The number of bytes to remove from the beginning of the pbuf list. + * While size >= p->len, pbufs are freed. + * ATTENTION: this is the opposite direction as @ref pbuf_header, but + * takes an u16_t not s16_t! + * @return the new head pbuf + */ +struct pbuf* +pbuf_free_header(struct pbuf *q, u16_t size) +{ + struct pbuf *p = q; + u16_t free_left = size; + while (free_left && p) { + s16_t free_len = (free_left > INT16_MAX ? INT16_MAX : (s16_t)free_left); + if (free_len >= p->len) { + struct pbuf *f = p; + free_left -= p->len; + p = p->next; + f->next = 0; + pbuf_free(f); + } else { + pbuf_header(p, -free_len); + free_left -= free_len; + } + } + return p; +} + /** * @ingroup pbuf * Dereference a pbuf chain or queue and deallocate any no-longer-used diff --git a/src/include/lwip/pbuf.h b/src/include/lwip/pbuf.h index c2238028..667c2383 100644 --- a/src/include/lwip/pbuf.h +++ b/src/include/lwip/pbuf.h @@ -248,6 +248,7 @@ struct pbuf *pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, void pbuf_realloc(struct pbuf *p, u16_t size); u8_t pbuf_header(struct pbuf *p, s16_t header_size); u8_t pbuf_header_force(struct pbuf *p, s16_t header_size); +struct pbuf *pbuf_free_header(struct pbuf *q, u16_t size); void pbuf_ref(struct pbuf *p); u8_t pbuf_free(struct pbuf *p); u16_t pbuf_clen(const struct pbuf *p);