Further update to ARP queueing: Changed pbuf_copy() implementation so that it can be reused (don't allocate the target pbuf inside pbuf_copy()).

This commit is contained in:
goldsimon 2007-05-04 21:31:25 +00:00
parent be316e81a7
commit 79d9b36ece
4 changed files with 67 additions and 24 deletions

View File

@ -129,6 +129,11 @@ HISTORY
++ Bug fixes: ++ Bug fixes:
2007-05-04 Simon Goldschmidt
* pbuf.c, pbuf.h, etharp.c: Further update to ARP queueing: Changed pbuf_copy()
implementation so that it can be reused (don't allocate the target
pbuf inside pbuf_copy()).
2007-05-04 Simon Goldschmidt 2007-05-04 Simon Goldschmidt
* memp.c: checked in patch #5913: in memp_malloc() we can return memp as mem * memp.c: checked in patch #5913: in memp_malloc() we can return memp as mem
to save a little RAM (next pointer of memp is not used while not in pool). to save a little RAM (next pointer of memp is not used while not in pool).

View File

@ -775,39 +775,73 @@ pbuf_dechain(struct pbuf *p)
* *
* @return Pointer to head of pbuf chain * @return Pointer to head of pbuf chain
*/ */
struct pbuf * err_t
pbuf_copy(struct pbuf *p) pbuf_copy(struct pbuf *p_to, struct pbuf *p_from)
{ {
u16_t copied=0; u16_t offset_to=0, offset_from=0, len;
struct pbuf *p_copy; #ifdef LWIP_DEBUG
LWIP_ASSERT("pbuf_copy: p != NULL\n", p != NULL); u16_t copied=0, shouldbe;
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE | 3, ("pbuf_copy(%p)\n", (void*)p)); #endif
/* allocate one pbuf to hold the complete packet */ LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE | 3, ("pbuf_copy(%p, %p)\n", p_to, p_from));
p_copy = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
if(p_copy == NULL) { /* is the target big enough to hold the source? */
/* out of memory */ if ((p_to == NULL) || (p_from == NULL) || (p_to->tot_len < p_from->tot_len)) {
return NULL; LWIP_ASSERT("pbuf_copy: p_to != NULL\n", p_to != NULL);
LWIP_ASSERT("pbuf_copy: p_from != NULL\n", p_from != NULL);
LWIP_ASSERT("pbuf_copy: p_to->tot_len >= p_from->tot_len\n", p_to->tot_len >= p_from->tot_len);
return ERR_ARG;
} }
#ifdef LWIP_DEBUG
shouldbe = p_from->tot_len;
#endif
/* iterate through pbuf chain */ /* iterate through pbuf chain */
do do
{ {
LWIP_ASSERT("p_to != NULL", p_to != NULL);
/* copy one part of the original chain */ /* copy one part of the original chain */
memcpy((char*)p_copy->payload + copied, p->payload, p->len); if ((p_to->len - offset_to) >= (p_from->len - offset_from)) {
copied += p->len; /* complete current p_from fits into current p_to */
LWIP_DEBUGF(PBUF_DEBUG, ("pbuf_copy: copied pbuf %p\n", (void *)p)); len = p_from->len - offset_from;
} else {
/* current p_from does not fit into current p_to */
len = p_to->len - offset_to;
}
memcpy((u8_t*)p_to->payload + offset_to, (u8_t*)p_from->payload + offset_from, len);
#ifdef LWIP_DEBUG
copied += len;
#endif
offset_to += len;
offset_from += len;
LWIP_ASSERT("offset_to <= p_to->len", offset_to <= p_to->len);
if (offset_to == p_to->len) {
/* on to next p_to (if any) */
offset_to = 0;
p_to = p_to->next;
}
LWIP_ASSERT("offset_from <= p_from->len", offset_to <= p_from->len);
if (offset_from >= p_from->len) {
/* on to next p_from (if any) */
offset_from = 0;
p_from = p_from->next;
}
if(p->len == p->tot_len) { if((p_from != NULL) && (p_from->len == p_from->tot_len)) {
/* don't copy more than one packet! */ /* don't copy more than one packet! */
LWIP_ASSERT("pbuf_copy() does not allow packet queues!\n", LWIP_ASSERT("pbuf_copy() does not allow packet queues!\n",
p->next == NULL); p_from->next == NULL);
} }
/* proceed to next pbuf in original chain */ if((p_to != NULL) && (p_to->len == p_to->tot_len)) {
p = p->next; /* don't copy more than one packet! */
} while (p); LWIP_ASSERT("pbuf_copy() does not allow packet queues!\n",
p_to->next == NULL);
}
} while (p_from);
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE | 1, ("pbuf_copy: end of chain reached.\n")); LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE | 1, ("pbuf_copy: end of chain reached.\n"));
#ifdef LWIP_DEBUG
return p_copy; LWIP_ASSERT("shouldbe == copied", shouldbe == copied);
#endif
return ERR_OK;
} }
#endif /* ARP_QUEUEING */ #endif /* ARP_QUEUEING */

View File

@ -34,7 +34,7 @@
#define __LWIP_PBUF_H__ #define __LWIP_PBUF_H__
#include "arch/cc.h" #include "arch/cc.h"
#include "lwip/err.h"
#define PBUF_TRANSPORT_HLEN 20 #define PBUF_TRANSPORT_HLEN 20
#define PBUF_IP_HLEN 20 #define PBUF_IP_HLEN 20
@ -107,7 +107,7 @@ void pbuf_cat(struct pbuf *h, struct pbuf *t);
void pbuf_chain(struct pbuf *h, struct pbuf *t); void pbuf_chain(struct pbuf *h, struct pbuf *t);
struct pbuf *pbuf_dechain(struct pbuf *p); struct pbuf *pbuf_dechain(struct pbuf *p);
#if ARP_QUEUEING #if ARP_QUEUEING
struct pbuf *pbuf_copy(struct pbuf *f); err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from);
#endif #endif
#endif /* __LWIP_PBUF_H__ */ #endif /* __LWIP_PBUF_H__ */

View File

@ -864,7 +864,11 @@ err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
} }
if(copy_needed) { if(copy_needed) {
/* copy the whole packet into new pbufs */ /* copy the whole packet into new pbufs */
p = pbuf_copy(q); p = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
if (pbuf_copy(p, q) != ERR_OK) {
pbuf_free(p);
p = NULL;
}
} else { } else {
/* referencing the old pbuf is enough */ /* referencing the old pbuf is enough */
p = q; p = q;