⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pbuf.c

📁 lwip在ucos上的移植源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2001, Swedish Institute of Computer Science. * All rights reserved.  * * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in the  *    documentation and/or other materials provided with the distribution.  * 3. Neither the name of the Institute nor the names of its contributors  *    may be used to endorse or promote products derived from this software  *    without specific prior written permission.  * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  * SUCH DAMAGE.  * * This file is part of the lwIP TCP/IP stack. *  * Author: Adam Dunkels <adam@sics.se> * * $Id: pbuf.c,v 1.1 2003/05/21 10:37:40 chenyu Exp $ *//*-----------------------------------------------------------------------------------*//* pbuf.c * * Functions for the manipulation of pbufs. The pbufs holds all packets in the * system. * *//*-----------------------------------------------------------------------------------*/#include "lwip/debug.h"#include "lwip/stats.h"#include "lwip/def.h"#include "lwip/mem.h"#include "lwip/memp.h"#include "lwip/pbuf.h"#include "lwip/sys.h"#include "arch/perf.h"static u8_t pbuf_pool_memory[(PBUF_POOL_SIZE * MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE + sizeof(struct pbuf)))];static volatile u8_t pbuf_pool_free_lock, pbuf_pool_alloc_lock;static sys_sem_t pbuf_pool_free_sem;static struct pbuf *pbuf_pool = NULL;static struct pbuf *pbuf_pool_alloc_cache = NULL;static struct pbuf *pbuf_pool_free_cache = NULL;/*-----------------------------------------------------------------------------------*//* pbuf_init(): * * Initializes the pbuf module. A large part of memory is allocated * for holding the pool of pbufs. The size of the individual pbufs in * the pool is given by the size parameter, and the number of pbufs in * the pool by the num parameter. * * After the memory has been allocated, the pbufs are set up. The * ->next pointer in each pbuf is set up to point to the next pbuf in * the pool. *//*-----------------------------------------------------------------------------------*/voidpbuf_init(void){  struct pbuf *p, *q;  u8_t i;  pbuf_pool = (struct pbuf *)&pbuf_pool_memory[0];  ASSERT("pbuf_init: pool aligned", (long)pbuf_pool % MEM_ALIGNMENT == 0);   #ifdef PBUF_STATS  stats.pbuf.avail = PBUF_POOL_SIZE;#endif /* PBUF_STATS */    /* Set up ->next pointers to link the pbufs of the pool together. */  p = pbuf_pool;    for(i = 0; i < PBUF_POOL_SIZE; ++i) {    p->next = (struct pbuf *)((u8_t *)p + PBUF_POOL_BUFSIZE + sizeof(struct pbuf));    p->len = p->tot_len = PBUF_POOL_BUFSIZE;    p->payload = MEM_ALIGN((void *)((u8_t *)p + sizeof(struct pbuf)));    q = p;    p = p->next;  }    /* The ->next pointer of last pbuf is NULL to indicate that there     are no more pbufs in the pool. */  q->next = NULL;  pbuf_pool_alloc_lock = 0;  pbuf_pool_free_lock = 0;  pbuf_pool_free_sem = sys_sem_new(1);  }/*-----------------------------------------------------------------------------------*//* The following two functions are only called from pbuf_alloc(). *//*-----------------------------------------------------------------------------------*/static struct pbuf *pbuf_pool_alloc(void){  struct pbuf *p = NULL;  /* First, see if there are pbufs in the cache. */  if(pbuf_pool_alloc_cache) {    p = pbuf_pool_alloc_cache;    if(p) {      pbuf_pool_alloc_cache = p->next;     }  } else {    /* Next, check the actual pbuf pool, but if the pool is locked, we       pretend to be out of buffers and return NULL. */    if(pbuf_pool_free_lock) {#ifdef PBUF_STATS      ++stats.pbuf.alloc_locked;#endif /* PBUF_STATS */      return NULL;    }    ++pbuf_pool_alloc_lock;    if(!pbuf_pool_free_lock) {      p = pbuf_pool;      if(p) {	pbuf_pool = p->next;       }#ifdef PBUF_STATS    } else {      ++stats.pbuf.alloc_locked;#endif /* PBUF_STATS */    }    --pbuf_pool_alloc_lock;  }#ifdef PBUF_STATS  if(p != NULL) {        ++stats.pbuf.used;    if(stats.pbuf.used > stats.pbuf.max) {      stats.pbuf.max = stats.pbuf.used;    }  }#endif /* PBUF_STATS */  return p;   }/*-----------------------------------------------------------------------------------*/static voidpbuf_pool_free(struct pbuf *p){  struct pbuf *q;#ifdef PBUF_STATS    for(q = p; q != NULL; q = q->next) {      --stats.pbuf.used;    }#endif /* PBUF_STATS */    if(pbuf_pool_alloc_cache == NULL) {    pbuf_pool_alloc_cache = p;  } else {      for(q = pbuf_pool_alloc_cache; q->next != NULL; q = q->next);    q->next = p;      }}/*-----------------------------------------------------------------------------------*//* pbuf_alloc(): * * Allocates a pbuf at protocol layer l. The actual memory allocated * for the pbuf is determined by the layer at which the pbuf is * allocated and the requested size (from the size parameter). The * flag parameter decides how and where the pbuf should be allocated * as follows: *  * * PBUF_RAM: buffer memory for pbuf is allocated as one large *             chunk. This includes protocol headers as well.  * * RBUF_ROM: no buffer memory is allocated for the pbuf, even for *             protocol headers. Additional headers must be prepended *             by allocating another pbuf and chain in to the front of *             the ROM pbuf.	        * * PBUF_ROOL: the pbuf is allocated as a pbuf chain, with pbufs from *              the pbuf pool that is allocated during pbuf_init(). *//*-----------------------------------------------------------------------------------*/struct pbuf *pbuf_alloc(pbuf_layer l, u16_t size, pbuf_flag flag){  struct pbuf *p, *q, *r;  u16_t offset;  s32_t rsize;  offset = 0;  switch(l) {  case PBUF_TRANSPORT:    offset += PBUF_TRANSPORT_HLEN;    /* FALLTHROUGH */  case PBUF_IP:    offset += PBUF_IP_HLEN;    offset += PBUF_LINK_HLEN;    /* FALLTHROUGH */  case PBUF_LINK:    break;  case PBUF_RAW:    break;  default:    ASSERT("pbuf_alloc: bad pbuf layer", 0);    return NULL;  }  switch(flag) {  case PBUF_POOL:    /* Allocate head of pbuf chain into p. */    p = pbuf_pool_alloc();    if(p == NULL) {#ifdef PBUF_STATS      ++stats.pbuf.err;#endif /* PBUF_STATS */      return NULL;    }    p->next = NULL;        /* Set the payload pointer so that it points offset bytes into       pbuf data memory. */    p->payload = MEM_ALIGN((void *)((u8_t *)p + (sizeof(struct pbuf) + offset)));    /* The total length of the pbuf is the requested size. */    p->tot_len = size;    /* Set the length of the first pbuf is the chain. */    p->len = size > PBUF_POOL_BUFSIZE - offset? PBUF_POOL_BUFSIZE - offset: size;    p->flags = PBUF_FLAG_POOL;        /* Allocate the tail of the pbuf chain. */    r = p;    rsize = size - p->len;    while(rsize > 0) {            q = pbuf_pool_alloc();      if(q == NULL) {	DEBUGF(PBUF_DEBUG, ("pbuf_alloc: Out of pbufs in pool,\n"));#ifdef PBUF_STATS        ++stats.pbuf.err;#endif /* PBUF_STATS */        pbuf_pool_free(p);        return NULL;      }      q->next = NULL;      r->next = q;      q->len = rsize > PBUF_POOL_BUFSIZE? PBUF_POOL_BUFSIZE: rsize;      q->flags = PBUF_FLAG_POOL;      q->payload = (void *)((u8_t *)q + sizeof(struct pbuf));      r = q;      q->ref = 1;      q = q->next;      rsize -= PBUF_POOL_BUFSIZE;    }    r->next = NULL;    ASSERT("pbuf_alloc: pbuf->payload properly aligned",	   ((u32_t)p->payload % MEM_ALIGNMENT) == 0);    break;  case PBUF_RAM:    /* If pbuf is to be allocated in RAM, allocate memory for it. */    p = mem_malloc(MEM_ALIGN_SIZE(sizeof(struct pbuf) + size + offset));    if(p == NULL) {      return NULL;    }    /* Set up internal structure of the pbuf. */    p->payload = MEM_ALIGN((void *)((u8_t *)p + sizeof(struct pbuf) + offset));    p->len = p->tot_len = size;    p->next = NULL;    p->flags = PBUF_FLAG_RAM;    ASSERT("pbuf_alloc: pbuf->payload properly aligned",	   ((u32_t)p->payload % MEM_ALIGNMENT) == 0);    break;  case PBUF_ROM:    /* If the pbuf should point to ROM, we only need to allocate       memory for the pbuf structure. */    p = memp_mallocp(MEMP_PBUF);    if(p == NULL) {      return NULL;    }    p->payload = NULL;    p->len = p->tot_len = size;    p->next = NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -