206 |
struct pbuf *p, *q, *r; |
struct pbuf *p, *q, *r; |
207 |
u16_t offset; |
u16_t offset; |
208 |
s32_t rem_len; /* remaining length */ |
s32_t rem_len; /* remaining length */ |
209 |
|
DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc(length=%u)\n", length)); |
210 |
|
|
211 |
/* determine header offset */ |
/* determine header offset */ |
212 |
offset = 0; |
offset = 0; |
234 |
case PBUF_POOL: |
case PBUF_POOL: |
235 |
/* allocate head of pbuf chain into p */ |
/* allocate head of pbuf chain into p */ |
236 |
p = pbuf_pool_alloc(); |
p = pbuf_pool_alloc(); |
237 |
|
DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc: allocated pbuf %p\n", p)); |
238 |
if (p == NULL) { |
if (p == NULL) { |
239 |
#ifdef PBUF_STATS |
#ifdef PBUF_STATS |
240 |
++lwip_stats.pbuf.err; |
++lwip_stats.pbuf.err; |
293 |
r = q; |
r = q; |
294 |
} |
} |
295 |
/* end of chain */ |
/* end of chain */ |
296 |
r->next = NULL; |
//r->next = NULL; |
297 |
|
|
298 |
break; |
break; |
299 |
case PBUF_RAM: |
case PBUF_RAM: |
333 |
} |
} |
334 |
/* set reference count */ |
/* set reference count */ |
335 |
p->ref = 1; |
p->ref = 1; |
336 |
|
DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc(length=%u) == %p\n", length, (void *)p)); |
337 |
return p; |
return p; |
338 |
} |
} |
339 |
|
|
537 |
DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_free(p == NULL) was called.\n")); |
DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_free(p == NULL) was called.\n")); |
538 |
return 0; |
return 0; |
539 |
} |
} |
540 |
|
DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_free(%p)\n", (void *)p)); |
541 |
|
|
542 |
PERF_START; |
PERF_START; |
543 |
|
|
561 |
if (p->ref == 0) { |
if (p->ref == 0) { |
562 |
/* remember next pbuf in chain for next iteration */ |
/* remember next pbuf in chain for next iteration */ |
563 |
q = p->next; |
q = p->next; |
564 |
|
DEBUGF( PBUF_DEBUG | 2, ("pbuf_free: deallocating %p\n", (void *)p)); |
565 |
/* is this a pbuf from the pool? */ |
/* is this a pbuf from the pool? */ |
566 |
if (p->flags == PBUF_FLAG_POOL) { |
if (p->flags == PBUF_FLAG_POOL) { |
567 |
p->len = p->tot_len = PBUF_POOL_BUFSIZE; |
p->len = p->tot_len = PBUF_POOL_BUFSIZE; |
580 |
/* p->ref > 0, this pbuf is still referenced to */ |
/* p->ref > 0, this pbuf is still referenced to */ |
581 |
/* (and so the remaining pbufs in chain as well) */ |
/* (and so the remaining pbufs in chain as well) */ |
582 |
} else { |
} else { |
583 |
|
DEBUGF( PBUF_DEBUG | 2, ("pbuf_free: %p has ref %u, ending here.\n", (void *)p, p->ref)); |
584 |
/* stop walking through chain */ |
/* stop walking through chain */ |
585 |
p = NULL; |
p = NULL; |
586 |
} |
} |
667 |
p->next = t; |
p->next = t; |
668 |
/* t is now referenced to one more time */ |
/* t is now referenced to one more time */ |
669 |
pbuf_ref(t); |
pbuf_ref(t); |
670 |
DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_chain: referencing tail %p\n", (void *) t)); |
DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_chain: %p references %p\n", (void *)p, (void *)t)); |
671 |
} |
} |
672 |
|
|
673 |
/* For packet queueing. Note that queued packets must be dequeued first |
/* For packet queueing. Note that queued packets must be dequeued first |
875 |
/* q is no longer referenced by p, free it */ |
/* q is no longer referenced by p, free it */ |
876 |
DEBUGF(PBUF_DEBUG | DBG_STATE, ("pbuf_dechain: unreferencing %p\n", (void *) q)); |
DEBUGF(PBUF_DEBUG | DBG_STATE, ("pbuf_dechain: unreferencing %p\n", (void *) q)); |
877 |
tail_gone = pbuf_free(q); |
tail_gone = pbuf_free(q); |
878 |
|
if (tail_gone > 0) DEBUGF(PBUF_DEBUG | DBG_STATE, ("pbuf_dechain: deallocated %p (as it is no longer referenced)\n", (void *) q)); |
879 |
/* return remaining tail or NULL if deallocated */ |
/* return remaining tail or NULL if deallocated */ |
880 |
} |
} |
881 |
/* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */ |
/* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */ |