📄 pbuf.c
字号:
p->flags = PBUF_FLAG_ROM; break; default: ASSERT("pbuf_alloc: erroneous flag", 0); return NULL; } p->ref = 1; return p;}/*-----------------------------------------------------------------------------------*//* pbuf_refresh(): * * Moves free buffers from the pbuf_pool_free_cache to the pbuf_pool * list (if possible). * *//*-----------------------------------------------------------------------------------*/voidpbuf_refresh(void){ struct pbuf *p; sys_sem_wait(pbuf_pool_free_sem); if(pbuf_pool_free_cache != NULL) { ++pbuf_pool_free_lock; if(!pbuf_pool_alloc_lock) { if(pbuf_pool == NULL) { pbuf_pool = pbuf_pool_free_cache; } else { for(p = pbuf_pool; p->next != NULL; p = p->next); p->next = pbuf_pool_free_cache; } pbuf_pool_free_cache = NULL;#ifdef PBUF_STATS } else { ++stats.pbuf.refresh_locked;#endif /* PBUF_STATS */ } --pbuf_pool_free_lock; } sys_sem_signal(pbuf_pool_free_sem);}#define PBUF_POOL_FREE(p) do { \ sys_sem_wait(pbuf_pool_free_sem); \ p->next = pbuf_pool_free_cache; \ pbuf_pool_free_cache = p; \ sys_sem_signal(pbuf_pool_free_sem); \ } while(0)/*-----------------------------------------------------------------------------------*//* 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. *//*-----------------------------------------------------------------------------------*/voidpbuf_realloc(struct pbuf *p, u16_t size){ struct pbuf *q, *r; u16_t rsize; 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);#ifdef PBUF_STATS --stats.pbuf.used;#endif /* PBUF_STATS */ 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. *//*-----------------------------------------------------------------------------------*/u8_tpbuf_header(struct pbuf *p, s16_t header_size){ void *payload; payload = p->payload; p->payload = (u8_t *)p->payload - header_size/sizeof(u8_t); 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_tpbuf_free(struct pbuf *p){ struct pbuf *q; u8_t count = 0; if(p == NULL) { return 0; } PERF_START; ASSERT("pbuf_free: sane flags", p->flags == PBUF_FLAG_POOL || p->flags == PBUF_FLAG_ROM || p->flags == PBUF_FLAG_RAM); ASSERT("pbuf_free: p->ref > 0", p->ref > 0); /* Decrement reference count. */ p->ref--; q = NULL; /* If reference count == 0, actually deallocate pbuf. */ if(p->ref == 0) { 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);#ifdef PBUF_STATS --stats.pbuf.used;#endif /* PBUF_STATS */ } 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(); } PERF_STOP("pbuf_free"); return count;}/*-----------------------------------------------------------------------------------*//* pbuf_clen(): * * Returns the length of the pbuf chain. *//*-----------------------------------------------------------------------------------*/u8_tpbuf_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. *//*-----------------------------------------------------------------------------------*/voidpbuf_ref(struct pbuf *p){ if(p == NULL) { return; } ++(p->ref);}/*-----------------------------------------------------------------------------------*//* pbuf_chain(): * * Chains the two pbufs h and t together. The ->tot_len field of the * first pbuf (h) is adjusted. *//*-----------------------------------------------------------------------------------*/voidpbuf_chain(struct pbuf *h, struct pbuf *t){ struct pbuf *p; 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;}/*-----------------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -