34 |
* |
* |
35 |
*/ |
*/ |
36 |
|
|
37 |
/*-----------------------------------------------------------------------------------*/ |
#define NEW_PBUF_REALLOC 1 /* should fix bug #1903 */ |
38 |
/* pbuf.c |
|
|
* |
|
|
* Functions for the manipulation of pbufs. The pbufs holds all packets in the |
|
|
* system. |
|
|
* |
|
|
*/ |
|
|
/*-----------------------------------------------------------------------------------*/ |
|
39 |
#include "lwip/opt.h" |
#include "lwip/opt.h" |
40 |
|
|
41 |
#include "lwip/stats.h" |
#include "lwip/stats.h" |
398 |
sys_sem_signal(pbuf_pool_free_sem); \ |
sys_sem_signal(pbuf_pool_free_sem); \ |
399 |
} while(0) |
} while(0) |
400 |
#endif /* SYS_LIGHTWEIGHT_PROT */ |
#endif /* SYS_LIGHTWEIGHT_PROT */ |
401 |
/*-----------------------------------------------------------------------------------*/ |
|
402 |
/* pbuf_realloc: |
/** |
403 |
|
* Shrink a pbuf chain to a certain size. |
404 |
* |
* |
405 |
* Reallocates the memory for a pbuf. If the pbuf is in ROM, this as |
* @param p pbuf to shrink. |
406 |
* simple as to adjust the ->tot_len and ->len fields. If the pbuf is |
* @param size new size |
407 |
|
* If the pbuf is in ROM, only the ->tot_len and ->len fields are adjusted. |
408 |
|
* If the chain |
409 |
* a pbuf chain, as it might be with both pbufs in dynamically |
* a pbuf chain, as it might be with both pbufs in dynamically |
410 |
* allocated RAM and for pbufs from the pbuf pool, we have to step |
* allocated RAM and for pbufs from the pbuf pool, we have to step |
411 |
* through the chain until we find the new endpoint in the pbuf chain. |
* through the chain until we find the new endpoint in the pbuf chain. |
412 |
* Then the pbuf that is right on the endpoint is resized and any |
* Then the pbuf that is right on the endpoint is resized and any |
413 |
* further pbufs on the chain are deallocated. |
* further pbufs on the chain are deallocated. |
414 |
|
* @bug #1903 |
415 |
*/ |
*/ |
416 |
/*-----------------------------------------------------------------------------------*/ |
/*-----------------------------------------------------------------------------------*/ |
417 |
|
#if NEW_PBUF_REALLOC |
418 |
|
void |
419 |
|
pbuf_realloc(struct pbuf *p, u16_t new_len) |
420 |
|
{ |
421 |
|
struct pbuf *q, *r; |
422 |
|
u16_t rem_len; /* remaining length */ |
423 |
|
|
424 |
|
LWIP_ASSERT("pbuf_realloc: sane p->flags", p->flags == PBUF_FLAG_POOL || |
425 |
|
p->flags == PBUF_FLAG_ROM || |
426 |
|
p->flags == PBUF_FLAG_RAM || |
427 |
|
p->flags == PBUF_FLAG_REF); |
428 |
|
|
429 |
|
if (new_len >= p->tot_len) { |
430 |
|
/** enlarging not yet supported */ |
431 |
|
return; |
432 |
|
} |
433 |
|
|
434 |
|
/* first, step over any pbufs that should remain in the chain */ |
435 |
|
rem_len = new_len; |
436 |
|
q = p; |
437 |
|
/* this pbuf should be kept? */ |
438 |
|
while (rem_len > q->len) { |
439 |
|
/* decrease remaining length by pbuf length */ |
440 |
|
rem_len -= q->len; |
441 |
|
q = q->next; |
442 |
|
} |
443 |
|
/* { we have now reached the new last pbuf } */ |
444 |
|
/* { rem_len == desired length for pbuf q } */ |
445 |
|
|
446 |
|
/* shrink allocated memory for PBUF_RAM */ |
447 |
|
/* (other types merely adjust their length fields */ |
448 |
|
if (q->flags == PBUF_FLAG_RAM) { |
449 |
|
/* reallocate and adjust the length of the pbuf that will be split */ |
450 |
|
mem_realloc(q, (u8_t *)q->payload - (u8_t *)q + rem_len); |
451 |
|
} |
452 |
|
|
453 |
|
q->len = rem_len; |
454 |
|
q->tot_len = q->len; |
455 |
|
|
456 |
|
/* deallocate any left over pbufs */ |
457 |
|
/* remember next pbuf in chain */ |
458 |
|
r = q->next; |
459 |
|
/* q is last packet in chain */ |
460 |
|
q->next = NULL; |
461 |
|
/* first pbuf to be dealloced */ |
462 |
|
q = r; |
463 |
|
/* any pbuf left? */ |
464 |
|
while(q != NULL) { |
465 |
|
/* remember next pbuf in chain */ |
466 |
|
r = q->next; |
467 |
|
/* deallocate pbuf */ |
468 |
|
if (q->flags == PBUF_FLAG_RAM) { |
469 |
|
pbuf_free(q); |
470 |
|
} else if ((q->flags == PBUF_FLAG_ROM) || (q->flags == PBUF_FLAG_REF)) { |
471 |
|
PBUF_POOL_FREE(q); |
472 |
|
} else if (q->flags == PBUF_FLAG_POOL) { |
473 |
|
PBUF_POOL_FREE(q); |
474 |
|
} |
475 |
|
q = r; |
476 |
|
} |
477 |
|
|
478 |
|
pbuf_refresh(); |
479 |
|
} |
480 |
|
#else /* pbuf_realloc() of CVS version 1.23 */ |
481 |
void |
void |
482 |
pbuf_realloc(struct pbuf *p, u16_t size) |
pbuf_realloc(struct pbuf *p, u16_t size) |
483 |
{ |
{ |
549 |
|
|
550 |
pbuf_refresh(); |
pbuf_refresh(); |
551 |
} |
} |
552 |
|
#endif |
553 |
|
|
554 |
/** |
/** |
555 |
* Decreases the header size by the given amount. |
* Decreases the header size by the given amount. |
556 |
* |
* |
853 |
|
|
854 |
return top; |
return top; |
855 |
} |
} |
856 |
|
|