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

📄 pbuf.c

📁 LwIP adaptation for Fujitsu MB90f497 and CS8900A Ethernet driver
💻 C
📖 第 1 页 / 共 2 页
字号:
}
/*-----------------------------------------------------------------------------------*/
/* pbuf_refresh():
 *
 * Moves free buffers from the pbuf_pool_free_cache to the pbuf_pool
 * list (if possible).
 *
 */
/*-----------------------------------------------------------------------------------*/
void
pbuf_refresh(void)
{
  struct pbuf *p;

  sys_sem_wait(pbuf_pool_free_sem);
  
  if(pbuf_pool_free_cache != NULL) {
    pbuf_pool_free_lock = 1;
    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 = 0;  
  }
  
  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.
 */
/*-----------------------------------------------------------------------------------*/
void
pbuf_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_t
pbuf_header(struct pbuf *p, s16_t header_size)
{
  void *payload;
  s16_t aux = -header_size;

  payload = p->payload;
  if(header_size>0) 
	  p->payload = (u8_t *)p->payload - header_size/sizeof(u8_t);
	else 
	p->payload = (u8_t *)p->payload + aux/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;
  }
  if(header_size>0) {
		  p->len += header_size;
		  p->tot_len += header_size;
		} else  {
		  p->len -= aux;
		  p->tot_len -= aux;
	        }
  
  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;
    
  if(p == NULL) {
    return 0;
  }
//   Put_String("\npbuf_free: ");

  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) {
//	Put_String("pbuf_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);
#ifdef PBUF_STATS 
	stats.varstats--;
#endif  	

      }
      p = q;
      ++count;
    }
    pbuf_refresh();
  }

  PERF_STOP("pbuf_free");
//  mprintf(count,4,0);
  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)
{
  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.
 */
/*-----------------------------------------------------------------------------------*/
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;
}
/*-----------------------------------------------------------------------------------*/

⌨️ 快捷键说明

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