pbuf.c
来自「Keil下移植好的lwip基于c166」· C语言 代码 · 共 732 行 · 第 1/2 页
C
732 行
#ifdef PBUF_STATS
#define DEC_PBUF_STATS do { --lwip_stats.pbuf.used; } while (0)
#else /* PBUF_STATS */
#define DEC_PBUF_STATS
#endif /* PBUF_STATS */
#define PBUF_POOL_FAST_FREE(p) do { \
p->next = pbuf_pool_free_cache; \
pbuf_pool_free_cache = p; \
DEC_PBUF_STATS; \
} while (0)
#if SYS_LIGHTWEIGHT_PROT
#define PBUF_POOL_FREE(p) do { \
SYS_ARCH_DECL_PROTECT(old_level); \
SYS_ARCH_PROTECT(old_level); \
PBUF_POOL_FAST_FREE(p); \
SYS_ARCH_UNPROTECT(old_level); \
} while(0)
#else /* SYS_LIGHTWEIGHT_PROT */
#define PBUF_POOL_FREE(p) do { \
sys_sem_wait(pbuf_pool_free_sem); \
PBUF_POOL_FAST_FREE(p); \
sys_sem_signal(pbuf_pool_free_sem); \
} while(0)
#endif /* SYS_LIGHTWEIGHT_PROT */
/*-----------------------------------------------------------------------------------*/
/* pbuf_realloc:
*
* Reallocates the memory for a pbuf. If the pbuf is in ROM, this as
* simple as to adjust the ->tot_len and ->len fields. If the pbuf is
* a pbuf chain, as it might be with both pbufs in dynamically
* allocated RAM and for pbufs from the pbuf pool, we have to step
* through the chain until we find the new endpoint in the pbuf chain.
* Then the pbuf that is right on the endpoint is resized and any
* further pbufs on the chain are deallocated.
*/
/*-----------------------------------------------------------------------------------*/
void
pbuf_realloc(struct pbuf *p, u16_t size)
{
struct pbuf *q, *r;
u16_t rsize;
LWIP_ASSERT("pbuf_realloc: sane p->flags", p->flags == PBUF_FLAG_POOL ||
p->flags == PBUF_FLAG_ROM ||
p->flags == PBUF_FLAG_RAM);
if(p->tot_len <= size) {
return;
}
switch(p->flags) {
case PBUF_FLAG_POOL:
/* First, step over any pbufs that should still be in the chain. */
rsize = size;
q = p;
while(rsize > q->len) {
rsize -= q->len;
q = q->next;
}
/* Adjust the length of the pbuf that will be halved. */
q->len = rsize;
/* And deallocate any left over pbufs. */
r = q->next;
q->next = NULL;
q = r;
while(q != NULL) {
r = q->next;
PBUF_POOL_FREE(q);
q = r;
}
break;
case PBUF_FLAG_ROM:
p->len = size;
break;
case PBUF_FLAG_RAM:
/* First, step over the pbufs that should still be in the chain. */
rsize = size;
q = p;
while(rsize > q->len) {
rsize -= q->len;
q = q->next;
}
if(q->flags == PBUF_FLAG_RAM) {
/* Reallocate and adjust the length of the pbuf that will be halved. */
mem_realloc(q, (u8_t *)q->payload - (u8_t *)q + rsize);
}
q->len = rsize;
/* And deallocate any left over pbufs. */
r = q->next;
q->next = NULL;
q = r;
while(q != NULL) {
r = q->next;
pbuf_free(q);
q = r;
}
break;
}
p->tot_len = size;
pbuf_refresh();
}
/*-----------------------------------------------------------------------------------*/
/* pbuf_header():
*
* Adjusts the ->payload pointer so that space for a header appears in
* the pbuf. Also, the ->tot_len and ->len fields are adjusted.
*
* Decreases the header size by the given amount.
* Using a negative value increases the header size.
*/
/*-----------------------------------------------------------------------------------*/
u8_t
pbuf_header(struct pbuf *p, s16_t header_size)
{
void *payload;
if(p->flags & PBUF_FLAG_ROM) {
return 1;
}
payload = p->payload;
p->payload = (u8_t *)p->payload - header_size;
DEBUGF(PBUF_DEBUG, ("pbuf_header: old %p new %p (%d)\n", payload, p->payload, header_size));
if((u8_t *)p->payload < (u8_t *)p + sizeof(struct pbuf)) {
DEBUGF(PBUF_DEBUG, ("pbuf_header: failed %p %p\n",
(u8_t *)p->payload,
(u8_t *)p + sizeof(struct pbuf)));
p->payload = payload;
return 1;
}
p->len += header_size;
p->tot_len += header_size;
return 0;
}
/*-----------------------------------------------------------------------------------*/
/* pbuf_free():
*
* Decrements the reference count and deallocates the pbuf if the
* reference count is zero. If the pbuf is a chain all pbufs in the
* chain are deallocated.
*/
/*-----------------------------------------------------------------------------------*/
u8_t
pbuf_free(struct pbuf *p)
{
struct pbuf *q;
u8_t count = 0;
SYS_ARCH_DECL_PROTECT(old_level);
if(p == NULL) {
return 0;
}
PERF_START;
/* *** CS *** TODO: re-enable this macro
LWIP_ASSERT("pbuf_free: sane flags", p->flags == PBUF_FLAG_POOL ||
p->flags == PBUF_FLAG_ROM ||
p->flags == PBUF_FLAG_RAM);
LWIP_ASSERT("pbuf_free: p->ref > 0", p->ref > 0);
*/
/* Since decrementing ref cannot be guarranteed to be a single machine operation
we must protect it. Also, the later test of ref must be protected.
*/
SYS_ARCH_PROTECT(old_level);
/* Decrement reference count. */
p->ref--;
/*q = NULL; DJH: Unnecessary statement*/
/* If reference count == 0, actually deallocate pbuf. */
if(p->ref == 0) {
SYS_ARCH_UNPROTECT(old_level);
while(p != NULL) {
/* Check if this is a pbuf from the pool. */
if(p->flags == PBUF_FLAG_POOL) {
p->len = p->tot_len = PBUF_POOL_BUFSIZE;
p->payload = (void *)((u8_t *)p + sizeof(struct pbuf));
q = p->next;
PBUF_POOL_FREE(p);
} else {
if(p->flags == PBUF_FLAG_ROM) {
q = p->next;
memp_freep(MEMP_PBUF, p);
} else {
q = p->next;
mem_free(p);
}
}
p = q;
++count;
}
pbuf_refresh();
}
else
SYS_ARCH_UNPROTECT(old_level);
PERF_STOP("pbuf_free");
return count;
}
/*-----------------------------------------------------------------------------------*/
/* pbuf_clen():
*
* Returns the length of the pbuf chain.
*/
/*-----------------------------------------------------------------------------------*/
u8_t
pbuf_clen(struct pbuf *p)
{
u8_t len;
if(p == NULL) {
return 0;
}
for(len = 0; p != NULL; p = p->next) {
++len;
}
return len;
}
/*-----------------------------------------------------------------------------------*/
/* pbuf_ref():
*
* Increments the reference count of the pbuf.
*/
/*-----------------------------------------------------------------------------------*/
void
pbuf_ref(struct pbuf *p)
{
SYS_ARCH_DECL_PROTECT(old_level);
if(p == NULL) {
return;
}
SYS_ARCH_PROTECT(old_level);
++(p->ref);
SYS_ARCH_UNPROTECT(old_level);
}
/*------------------------------------------------------------------------------*/
/* pbuf_ref_chain():
*
* Increments the reference count of all pbufs in a chain.
*/
void
pbuf_ref_chain(struct pbuf *p)
{
SYS_ARCH_DECL_PROTECT(old_level);
SYS_ARCH_PROTECT(old_level);
while (p != NULL) {
p->ref++;
p=p->next;
}
SYS_ARCH_UNPROTECT(old_level);
}
/*-----------------------------------------------------------------------------------*/
/* pbuf_chain():
*
* Chains the two pbufs h and t together. The ->tot_len field of the
* first pbuf (h) is adjusted.
*/
/*-----------------------------------------------------------------------------------*/
void
pbuf_chain(struct pbuf *h, struct pbuf *t)
{
struct pbuf *p;
if(t == NULL) {
return;
}
for(p = h; p->next != NULL; p = p->next);
p->next = t;
h->tot_len += t->tot_len;
}
/*-----------------------------------------------------------------------------------*/
/* pbuf_dechain():
*
* Adjusts the ->tot_len field of the pbuf and returns the tail (if
* any) of the pbuf chain.
*/
/*-----------------------------------------------------------------------------------*/
struct pbuf *
pbuf_dechain(struct pbuf *p)
{
struct pbuf *q;
q = p->next;
if (q != NULL) {
q->tot_len = p->tot_len - p->len;
}
p->tot_len = p->len;
p->next = NULL;
return q;
}
/*-----------------------------------------------------------------------------------*/
struct pbuf *
pbuf_unref(struct pbuf *f)
{
struct pbuf *p, *q;
DEBUGF(PBUF_DEBUG, ("pbuf_unref: %p \n", (void*)f));
/* first pbuf is of type PBUF_REF? */
if (f->flags == PBUF_FLAG_REF)
{
/* allocate a pbuf (w/ payload) fully in RAM */
p = pbuf_alloc(PBUF_RAW, f->len, PBUF_RAM);
if (p != 0)
{
int i;
unsigned char *src, *dst;
/* copy pbuf struct */
p->next = f->next;
src = f->payload;
dst = p->payload;
i = 0;
/* copy payload to RAM pbuf */
while(i < p->len)
{
*dst = *src;
dst++;
src++;
}
f->next = NULL;
/* de-allocate PBUF_REF */
pbuf_free(f);
f = p;
DEBUGF(PBUF_DEBUG, ("pbuf_unref: succesful %p \n", (void *)f));
}
else
{
/* deallocate chain */
pbuf_free(f);
f = NULL;
DEBUGF(PBUF_DEBUG, ("pbuf_unref: failed\n"));
return NULL;
}
}
/* p = previous pbuf == first pbuf */
p = f;
/* q = current pbuf */
q = f->next;
while (q != NULL)
{
q = q->next;
}
return f;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?