pbuf.c
上传用户:yyhongfa
上传日期:2013-01-18
资源大小:267k
文件大小:32k
开发平台:

C/C++

  1. /**
  2.  * @file
  3.  * Packet buffer management
  4.  *
  5.  * Packets are built from the pbuf data structure. It supports dynamic
  6.  * memory allocation for packet contents or can reference externally
  7.  * managed packet contents both in RAM and ROM. Quick allocation for
  8.  * incoming packets is provided through pools with fixed sized pbufs.
  9.  *
  10.  * A packet may span over multiple pbufs, chained as a singly linked
  11.  * list. This is called a "pbuf chain".
  12.  *
  13.  * Multiple packets may be queued, also using this singly linked list.
  14.  * This is called a "packet queue".
  15.  * 
  16.  * So, a packet queue consists of one or more pbuf chains, each of
  17.  * which consist of one or more pbufs. Currently, queues are only
  18.  * supported in a limited section of lwIP, this is the etharp queueing
  19.  * code. Outside of this section no packet queues are supported yet.
  20.  * 
  21.  * The differences between a pbuf chain and a packet queue are very
  22.  * precise but subtle. 
  23.  *
  24.  * The last pbuf of a packet has a ->tot_len field that equals the
  25.  * ->len field. It can be found by traversing the list. If the last
  26.  * pbuf of a packet has a ->next field other than NULL, more packets
  27.  * are on the queue.
  28.  *
  29.  * Therefore, looping through a pbuf of a single packet, has an
  30.  * loop end condition (tot_len == p->len), NOT (next == NULL).
  31.  */
  32. /*
  33.  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
  34.  * All rights reserved.
  35.  *
  36.  * Redistribution and use in source and binary forms, with or without modification,
  37.  * are permitted provided that the following conditions are met:
  38.  *
  39.  * 1. Redistributions of source code must retain the above copyright notice,
  40.  *    this list of conditions and the following disclaimer.
  41.  * 2. Redistributions in binary form must reproduce the above copyright notice,
  42.  *    this list of conditions and the following disclaimer in the documentation
  43.  *    and/or other materials provided with the distribution.
  44.  * 3. The name of the author may not be used to endorse or promote products
  45.  *    derived from this software without specific prior written permission.
  46.  *
  47.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  48.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  49.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
  50.  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  51.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
  52.  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  53.  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  54.  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  55.  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  56.  * OF SUCH DAMAGE.
  57.  *
  58.  * This file is part of the lwIP TCP/IP stack.
  59.  *
  60.  * Author: Adam Dunkels <adam@sics.se>
  61.  *
  62.  */
  63. #include "lwip/opt.h"
  64. #include "lwip/stats.h"
  65. #include "lwip/def.h"
  66. #include "lwip/mem.h"
  67. #include "lwip/memp.h"
  68. #include "lwip/pbuf.h"
  69. #include "lwip/sys.h"
  70. #include "arch/perf.h"
  71. #include "uart.h"
  72. static u8_t pbuf_pool_memory[(PBUF_POOL_SIZE * MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE + sizeof(struct pbuf)))];
  73. #if !SYS_LIGHTWEIGHT_PROT
  74. static volatile u8_t pbuf_pool_free_lock, pbuf_pool_alloc_lock;
  75. static sys_sem_t pbuf_pool_free_sem;
  76. #endif
  77. static struct pbuf *pbuf_pool = NULL;
  78. /**
  79.  * Initializes the pbuf module.
  80.  *
  81.  * A large part of memory is allocated for holding the pool of pbufs.
  82.  * The size of the individual pbufs in the pool is given by the size
  83.  * parameter, and the number of pbufs in the pool by the num parameter.
  84.  *
  85.  * After the memory has been allocated, the pbufs are set up. The
  86.  * ->next pointer in each pbuf is set up to point to the next pbuf in
  87.  * the pool.
  88.  *
  89.  */
  90. void
  91. pbuf_init(void)
  92. {
  93.   struct pbuf *p, *q = NULL;
  94.   u16_t i;
  95.   pbuf_pool = (struct pbuf *)&pbuf_pool_memory[0];
  96.   LWIP_ASSERT("pbuf_init: pool aligned", (mem_ptr_t)pbuf_pool % MEM_ALIGNMENT == 0);
  97. #if PBUF_STATS
  98.   lwip_stats.pbuf.avail = PBUF_POOL_SIZE;
  99. #endif /* PBUF_STATS */
  100.   /* Set up ->next pointers to link the pbufs of the pool together */
  101.   p = pbuf_pool;
  102.   for(i = 0; i < PBUF_POOL_SIZE; ++i) {
  103.     p->next = (struct pbuf *)((u8_t *)p + PBUF_POOL_BUFSIZE + sizeof(struct pbuf));
  104.     p->len = p->tot_len = PBUF_POOL_BUFSIZE;
  105.     p->payload = MEM_ALIGN((void *)((u8_t *)p + sizeof(struct pbuf)));
  106.     p->flags = PBUF_FLAG_POOL;
  107.     q = p;
  108.     p = p->next;
  109.   }
  110.   /* The ->next pointer of last pbuf is NULL to indicate that there
  111.      are no more pbufs in the pool */
  112.   q->next = NULL;
  113. #if !SYS_LIGHTWEIGHT_PROT
  114.   pbuf_pool_alloc_lock = 0;
  115.   pbuf_pool_free_lock = 0;
  116.   pbuf_pool_free_sem = sys_sem_new(1);
  117. #endif
  118. }
  119. /**
  120.  * @internal only called from pbuf_alloc()
  121.  */
  122. static struct pbuf *
  123. pbuf_pool_alloc(void)
  124. {
  125.   struct pbuf *p = NULL;
  126.   SYS_ARCH_DECL_PROTECT(old_level);
  127.   SYS_ARCH_PROTECT(old_level);
  128.   //DEBUG_FUNCTION("pbuf_pool_alloc()");
  129. #if !SYS_LIGHTWEIGHT_PROT
  130.   /* Next, check the actual pbuf pool, but if the pool is locked, we
  131.      pretend to be out of buffers and return NULL. */
  132.   if (pbuf_pool_free_lock) {
  133. #if PBUF_STATS
  134.     ++lwip_stats.pbuf.alloc_locked;
  135. #endif /* PBUF_STATS */
  136.     return NULL;
  137.   }
  138.   pbuf_pool_alloc_lock = 1;
  139.   if (!pbuf_pool_free_lock) {
  140. #endif /* SYS_LIGHTWEIGHT_PROT */
  141.     p = pbuf_pool;
  142.     if (p) {
  143.       pbuf_pool = p->next;
  144.     }
  145. #if !SYS_LIGHTWEIGHT_PROT
  146. #if PBUF_STATS
  147.   } else {
  148.     ++lwip_stats.pbuf.alloc_locked;
  149. #endif /* PBUF_STATS */
  150.   }
  151.   pbuf_pool_alloc_lock = 0;
  152. #endif /* SYS_LIGHTWEIGHT_PROT */
  153. #if PBUF_STATS
  154.   if (p != NULL) {
  155.     ++lwip_stats.pbuf.used;
  156.     if (lwip_stats.pbuf.used > lwip_stats.pbuf.max) {
  157.       lwip_stats.pbuf.max = lwip_stats.pbuf.used;
  158.     }
  159.   }
  160. #endif /* PBUF_STATS */
  161.   SYS_ARCH_UNPROTECT(old_level);
  162.   return p;
  163. }
  164. /**
  165.  * Allocates a pbuf of the given type (possibly a chain for PBUF_POOL type).
  166.  *
  167.  * The actual memory allocated for the pbuf is determined by the
  168.  * layer at which the pbuf is allocated and the requested size
  169.  * (from the size parameter).
  170.  *
  171.  * @param flag this parameter decides how and where the pbuf
  172.  * should be allocated as follows:
  173.  *
  174.  * - PBUF_RAM: buffer memory for pbuf is allocated as one large
  175.  *             chunk. This includes protocol headers as well.
  176.  * - PBUF_ROM: no buffer memory is allocated for the pbuf, even for
  177.  *             protocol headers. Additional headers must be prepended
  178.  *             by allocating another pbuf and chain in to the front of
  179.  *             the ROM pbuf. It is assumed that the memory used is really
  180.  *             similar to ROM in that it is immutable and will not be
  181.  *             changed. Memory which is dynamic should generally not
  182.  *             be attached to PBUF_ROM pbufs. Use PBUF_REF instead.
  183.  * - PBUF_REF: no buffer memory is allocated for the pbuf, even for
  184.  *             protocol headers. It is assumed that the pbuf is only
  185.  *             being used in a single thread. If the pbuf gets queued,
  186.  *             then pbuf_take should be called to copy the buffer.
  187.  * - PBUF_POOL: the pbuf is allocated as a pbuf chain, with pbufs from
  188.  *              the pbuf pool that is allocated during pbuf_init().
  189.  *
  190.  * @return the allocated pbuf. If multiple pbufs where allocated, this
  191.  * is the first pbuf of a pbuf chain.
  192.  */
  193. struct pbuf *
  194. pbuf_alloc(pbuf_layer l, u16_t length, pbuf_flag flag)
  195. {
  196.   struct pbuf *p, *q, *r;
  197.   u16_t offset;
  198.   s32_t rem_len; /* remaining length */
  199.   LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc(length=%u)n", length));
  200.   /* determine header offset */
  201.   offset = 0;
  202.   switch (l) {
  203.   case PBUF_TRANSPORT:
  204.     /* add room for transport (often TCP) layer header */
  205.     offset += PBUF_TRANSPORT_HLEN;
  206.     /* FALLTHROUGH */
  207.   case PBUF_IP:
  208.     /* add room for IP layer header */
  209.     offset += PBUF_IP_HLEN;
  210.     /* FALLTHROUGH */
  211.   case PBUF_LINK:
  212.     /* add room for link layer header */
  213.     offset += PBUF_LINK_HLEN;
  214.     break;
  215.   case PBUF_RAW:
  216.     break;
  217.   default:
  218.     LWIP_ASSERT("pbuf_alloc: bad pbuf layer", 0);
  219.     return NULL;
  220.   }
  221.   switch (flag) {
  222.   case PBUF_POOL:
  223.     /* allocate head of pbuf chain into p */
  224.     p = pbuf_pool_alloc();
  225.     LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc: allocated pbuf %pn", (void *)p));
  226.     if (p == NULL) {
  227. #if PBUF_STATS
  228.       ++lwip_stats.pbuf.err;
  229. #endif /* PBUF_STATS */
  230.       DEBUG_ERR("pbuf_pool_alloc, but return NULL");
  231.       return NULL;
  232.     }
  233.     p->next = NULL;
  234.     /* make the payload pointer point 'offset' bytes into pbuf data memory */
  235.     p->payload = MEM_ALIGN((void *)((u8_t *)p + (sizeof(struct pbuf) + offset)));
  236.     LWIP_ASSERT("pbuf_alloc: pbuf p->payload properly aligned",
  237.             ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0);
  238.     /* the total length of the pbuf chain is the requested size */
  239.     p->tot_len = length;
  240.     /* set the length of the first pbuf in the chain */
  241.     p->len = length > PBUF_POOL_BUFSIZE - offset? PBUF_POOL_BUFSIZE - offset: length;
  242.     /* set reference count (needed here in case we fail) */
  243.     p->ref = 1;
  244.     /* now allocate the tail of the pbuf chain */
  245.     /* remember first pbuf for linkage in next iteration */
  246.     r = p;
  247.     /* remaining length to be allocated */
  248.     rem_len = length - p->len;
  249.     /* any remaining pbufs to be allocated? */
  250.     while (rem_len > 0) {
  251.       q = pbuf_pool_alloc();
  252.       if (q == NULL) {
  253.        LWIP_DEBUGF(PBUF_DEBUG | 2, ("pbuf_alloc: Out of pbufs in pool.n"));
  254. #if PBUF_STATS
  255.         ++lwip_stats.pbuf.err;
  256. #endif /* PBUF_STATS */
  257.         /* free chain so far allocated */
  258.         pbuf_free(p);
  259.         /* bail out unsuccesfully */
  260.  DEBUG_ERR("pbuf_alloc: Out of pbufs in pool.");
  261.         return NULL;
  262.       }
  263.       q->next = NULL;
  264.       /* make previous pbuf point to this pbuf */
  265.       r->next = q;
  266.       /* set total length of this pbuf and next in chain */
  267.       q->tot_len = rem_len;
  268.       /* this pbuf length is pool size, unless smaller sized tail */
  269.       q->len = rem_len > PBUF_POOL_BUFSIZE? PBUF_POOL_BUFSIZE: rem_len;
  270.       q->payload = (void *)((u8_t *)q + sizeof(struct pbuf));
  271.       LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned",
  272.               ((mem_ptr_t)q->payload % MEM_ALIGNMENT) == 0);
  273.       q->ref = 1;
  274.       /* calculate remaining length to be allocated */
  275.       rem_len -= q->len;
  276.       /* remember this pbuf for linkage in next iteration */
  277.       r = q;
  278.     }
  279.     /* end of chain */
  280.     /*r->next = NULL;*/
  281.     break;
  282.   case PBUF_RAM:
  283.     /* If pbuf is to be allocated in RAM, allocate memory for it. */
  284.     p = mem_malloc(MEM_ALIGN_SIZE(sizeof(struct pbuf) + offset) + MEM_ALIGN_SIZE(length));
  285.     if (p == NULL) {
  286. DEBUG_ERR("mem_malloc: but return NULL.");
  287.       return NULL;
  288.     }
  289.     /* Set up internal structure of the pbuf. */
  290.     p->payload = MEM_ALIGN((void *)((u8_t *)p + sizeof(struct pbuf) + offset));
  291.     p->len = p->tot_len = length;
  292.     p->next = NULL;
  293.     p->flags = PBUF_FLAG_RAM;
  294.     LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned",
  295.            ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0);
  296.     break;
  297.   /* pbuf references existing (non-volatile static constant) ROM payload? */
  298.   case PBUF_ROM:
  299.   /* pbuf references existing (externally allocated) RAM payload? */
  300.   case PBUF_REF:
  301.     /* only allocate memory for the pbuf structure */
  302.     p = memp_malloc(MEMP_PBUF);
  303.     if (p == NULL) {
  304.       LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_alloc: Could not allocate MEMP_PBUF for PBUF_%s.n", flag == PBUF_ROM?"ROM":"REF"));
  305.       return NULL;
  306.     }
  307.     /* caller must set this field properly, afterwards */
  308.     p->payload = NULL;
  309.     p->len = p->tot_len = length;
  310.     p->next = NULL;
  311.     p->flags = (flag == PBUF_ROM? PBUF_FLAG_ROM: PBUF_FLAG_REF);
  312.     break;
  313.   default:
  314.     LWIP_ASSERT("pbuf_alloc: erroneous flag", 0);
  315.     return NULL;
  316.   }
  317.   /* set reference count */
  318.   p->ref = 1;
  319.   LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_alloc(length=%u) == %pn", length, (void *)p));
  320.   return p;
  321. }
  322. #if PBUF_STATS
  323. #define DEC_PBUF_STATS do { --lwip_stats.pbuf.used; } while (0)
  324. #else /* PBUF_STATS */
  325. #define DEC_PBUF_STATS
  326. #endif /* PBUF_STATS */
  327. #define PBUF_POOL_FAST_FREE(p)  do {                                    
  328.                                   p->next = pbuf_pool;                  
  329.                                   pbuf_pool = p;                        
  330.                                   DEC_PBUF_STATS;                       
  331.                                 } while (0)
  332. #if SYS_LIGHTWEIGHT_PROT
  333. #define PBUF_POOL_FREE(p)  do {                                         
  334.                                 SYS_ARCH_DECL_PROTECT(old_level);       
  335.                                 SYS_ARCH_PROTECT(old_level);            
  336.                                 PBUF_POOL_FAST_FREE(p);                 
  337.                                 SYS_ARCH_UNPROTECT(old_level);          
  338.                                } while (0)
  339. #else /* SYS_LIGHTWEIGHT_PROT */
  340. #define PBUF_POOL_FREE(p)  do {                                         
  341.                              sys_sem_wait(pbuf_pool_free_sem);          
  342.                              PBUF_POOL_FAST_FREE(p);                    
  343.                              sys_sem_signal(pbuf_pool_free_sem);        
  344.                            } while (0)
  345. #endif /* SYS_LIGHTWEIGHT_PROT */
  346. /**
  347.  * Shrink a pbuf chain to a desired length.
  348.  *
  349.  * @param p pbuf to shrink.
  350.  * @param new_len desired new length of pbuf chain
  351.  *
  352.  * Depending on the desired length, the first few pbufs in a chain might
  353.  * be skipped and left unchanged. The new last pbuf in the chain will be
  354.  * resized, and any remaining pbufs will be freed.
  355.  *
  356.  * @note If the pbuf is ROM/REF, only the ->tot_len and ->len fields are adjusted.
  357.  * @note May not be called on a packet queue.
  358.  *
  359.  * @bug Cannot grow the size of a pbuf (chain) (yet).
  360.  */
  361. void
  362. pbuf_realloc(struct pbuf *p, u16_t new_len)
  363. {
  364.   struct pbuf *q;
  365.   u16_t rem_len; /* remaining length */
  366.   s16_t grow;
  367.   LWIP_ASSERT("pbuf_realloc: sane p->flags", p->flags == PBUF_FLAG_POOL ||
  368.               p->flags == PBUF_FLAG_ROM ||
  369.               p->flags == PBUF_FLAG_RAM ||
  370.               p->flags == PBUF_FLAG_REF);
  371.   /* desired length larger than current length? */
  372.   if (new_len >= p->tot_len) {
  373.     /* enlarging not yet supported */
  374.     return;
  375.   }
  376.   /* the pbuf chain grows by (new_len - p->tot_len) bytes
  377.    * (which may be negative in case of shrinking) */
  378.   grow = new_len - p->tot_len;
  379.   /* first, step over any pbufs that should remain in the chain */
  380.   rem_len = new_len;
  381.   q = p;
  382.   /* should this pbuf be kept? */
  383.   while (rem_len > q->len) {
  384.     /* decrease remaining length by pbuf length */
  385.     rem_len -= q->len;
  386.     /* decrease total length indicator */
  387.     q->tot_len += grow;
  388.     /* proceed to next pbuf in chain */
  389.     q = q->next;
  390.   }
  391.   /* we have now reached the new last pbuf (in q) */
  392.   /* rem_len == desired length for pbuf q */
  393.   /* shrink allocated memory for PBUF_RAM */
  394.   /* (other types merely adjust their length fields */
  395.   if ((q->flags == PBUF_FLAG_RAM) && (rem_len != q->len)) {
  396.     /* reallocate and adjust the length of the pbuf that will be split */
  397.     mem_realloc(q, (u8_t *)q->payload - (u8_t *)q + rem_len);
  398.   }
  399.   /* adjust length fields for new last pbuf */
  400.   q->len = rem_len;
  401.   q->tot_len = q->len;
  402.   /* any remaining pbufs in chain? */
  403.   if (q->next != NULL) {
  404.     /* free remaining pbufs in chain */
  405.     pbuf_free(q->next);
  406.   }
  407.   /* q is last packet in chain */
  408.   q->next = NULL;
  409. }
  410. /**
  411.  * Adjusts the payload pointer to hide or reveal headers in the payload.
  412.  *
  413.  * Adjusts the ->payload pointer so that space for a header
  414.  * (dis)appears in the pbuf payload.
  415.  *
  416.  * The ->payload, ->tot_len and ->len fields are adjusted.
  417.  *
  418.  * @param hdr_size_inc Number of bytes to increment header size which
  419.  * increases the size of the pbuf. New space is on the front.
  420.  * (Using a negative value decreases the header size.)
  421.  * If hdr_size_inc is 0, this function does nothing and returns succesful.
  422.  *
  423.  * PBUF_ROM and PBUF_REF type buffers cannot have their sizes increased, so
  424.  * the call will fail. A check is made that the increase in header size does
  425.  * not move the payload pointer in front of the start of the buffer.
  426.  * @return non-zero on failure, zero on success.
  427.  *
  428.  */
  429. u8_t
  430. pbuf_header(struct pbuf *p, s16_t header_size_increment)
  431. {
  432.   void *payload;
  433.   LWIP_ASSERT("p != NULL", p != NULL);
  434.   if ((header_size_increment == 0) || (p == NULL)) return 0;
  435.  
  436.   /* remember current payload pointer */
  437.   payload = p->payload;
  438.   /* pbuf types containing payloads? */
  439.   if (p->flags == PBUF_FLAG_RAM || p->flags == PBUF_FLAG_POOL) {
  440.     /* set new payload pointer */
  441.     p->payload = (u8_t *)p->payload - header_size_increment;
  442.     /* boundary check fails? */
  443.     if ((u8_t *)p->payload < (u8_t *)p + sizeof(struct pbuf)) {
  444.       LWIP_DEBUGF( PBUF_DEBUG | 2, ("pbuf_header: failed as %p < %p (not enough space for new header size)n",
  445.         (void *)p->payload,
  446.         (void *)(p + 1)));
  447.       /* restore old payload pointer */
  448.       p->payload = payload;
  449.       /* bail out unsuccesfully */
  450.       return 1;
  451.     }
  452.   /* pbuf types refering to external payloads? */
  453.   } else if (p->flags == PBUF_FLAG_REF || p->flags == PBUF_FLAG_ROM) {
  454.     /* hide a header in the payload? */
  455.     if ((header_size_increment < 0) && (header_size_increment - p->len <= 0)) {
  456.       /* increase payload pointer */
  457.       p->payload = (u8_t *)p->payload - header_size_increment;
  458.     } else {
  459.       /* cannot expand payload to front (yet!)
  460.        * bail out unsuccesfully */
  461.       return 1;
  462.     }
  463.   }
  464.   /* modify pbuf length fields */
  465.   p->len += header_size_increment;
  466.   p->tot_len += header_size_increment;
  467.   LWIP_DEBUGF( PBUF_DEBUG, ("pbuf_header: old %p new %p (%d)n",
  468.     (void *)payload, (void *)p->payload, header_size_increment));
  469.   return 0;
  470. }
  471. /**
  472.  * Dereference a pbuf chain or queue and deallocate any no-longer-used
  473.  * pbufs at the head of this chain or queue.
  474.  *
  475.  * Decrements the pbuf reference count. If it reaches zero, the pbuf is
  476.  * deallocated.
  477.  *
  478.  * For a pbuf chain, this is repeated for each pbuf in the chain,
  479.  * up to the first pbuf which has a non-zero reference count after
  480.  * decrementing. So, when all reference counts are one, the whole
  481.  * chain is free'd.
  482.  *
  483.  * @param pbuf The pbuf (chain) to be dereferenced.
  484.  *
  485.  * @return the number of pbufs that were de-allocated
  486.  * from the head of the chain.
  487.  *
  488.  * @note MUST NOT be called on a packet queue (Not verified to work yet).
  489.  * @note the reference counter of a pbuf equals the number of pointers
  490.  * that refer to the pbuf (or into the pbuf).
  491.  *
  492.  * @internal examples:
  493.  *
  494.  * Assuming existing chains a->b->c with the following reference
  495.  * counts, calling pbuf_free(a) results in:
  496.  * 
  497.  * 1->2->3 becomes ...1->3
  498.  * 3->3->3 becomes 2->3->3
  499.  * 1->1->2 becomes ......1
  500.  * 2->1->1 becomes 1->1->1
  501.  * 1->1->1 becomes .......
  502.  *
  503.  */
  504. u8_t
  505. pbuf_free(struct pbuf *p)
  506. {
  507.   struct pbuf *q;
  508.   u8_t count;
  509.   SYS_ARCH_DECL_PROTECT(old_level);
  510.   LWIP_ASSERT("p != NULL", p != NULL);
  511.   /* if assertions are disabled, proceed with debug output */
  512.   if (p == NULL) {
  513.     LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_free(p == NULL) was called.n"));
  514.     return 0;
  515.   }
  516.   LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_free(%p)n", (void *)p));
  517.   PERF_START;
  518.   LWIP_ASSERT("pbuf_free: sane flags",
  519.     p->flags == PBUF_FLAG_RAM || p->flags == PBUF_FLAG_ROM ||
  520.     p->flags == PBUF_FLAG_REF || p->flags == PBUF_FLAG_POOL);
  521.   count = 0;
  522.   /* Since decrementing ref cannot be guaranteed to be a single machine operation
  523.    * we must protect it. Also, the later test of ref must be protected.
  524.    */
  525.   SYS_ARCH_PROTECT(old_level);
  526.   /* de-allocate all consecutive pbufs from the head of the chain that
  527.    * obtain a zero reference count after decrementing*/
  528.   while (p != NULL) {
  529.     /* all pbufs in a chain are referenced at least once */
  530.     LWIP_ASSERT("pbuf_free: p->ref > 0", p->ref > 0);
  531.     /* decrease reference count (number of pointers to pbuf) */
  532.     p->ref--;
  533.     /* this pbuf is no longer referenced to? */
  534.     if (p->ref == 0) {
  535.       /* remember next pbuf in chain for next iteration */
  536.       q = p->next;
  537.       LWIP_DEBUGF( PBUF_DEBUG | 2, ("pbuf_free: deallocating %pn", (void *)p));
  538.       /* is this a pbuf from the pool? */
  539.       if (p->flags == PBUF_FLAG_POOL) {
  540.         p->len = p->tot_len = PBUF_POOL_BUFSIZE;
  541.         p->payload = (void *)((u8_t *)p + sizeof(struct pbuf));
  542.         PBUF_POOL_FREE(p);
  543.    //DEBUG_EVENT("pbuf free : PBUF_FLAG_POOL.");
  544.       /* is this a ROM or RAM referencing pbuf? */
  545.       } else if (p->flags == PBUF_FLAG_ROM || p->flags == PBUF_FLAG_REF) {
  546.         memp_free(MEMP_PBUF, p);
  547.       /* p->flags == PBUF_FLAG_RAM */
  548.       } else {
  549.         mem_free(p);
  550.       }
  551.       count++;
  552.       /* proceed to next pbuf */
  553.       p = q;
  554.     /* p->ref > 0, this pbuf is still referenced to */
  555.     /* (and so the remaining pbufs in chain as well) */
  556.     } else {
  557.       LWIP_DEBUGF( PBUF_DEBUG | 2, ("pbuf_free: %p has ref %u, ending here.n", (void *)p, (unsigned int)p->ref));
  558.       /* stop walking through the chain */
  559.       p = NULL;
  560.     }
  561.   }
  562.   SYS_ARCH_UNPROTECT(old_level);
  563.  // PERF_STOP("pbuf_free");
  564.   /* return number of de-allocated pbufs */
  565.   return count;
  566. }
  567. /**
  568.  * Count number of pbufs in a chain
  569.  *
  570.  * @param p first pbuf of chain
  571.  * @return the number of pbufs in a chain
  572.  */
  573. u8_t
  574. pbuf_clen(struct pbuf *p)
  575. {
  576.   u8_t len;
  577.   len = 0;
  578.   while (p != NULL) {
  579.     ++len;
  580.     p = p->next;
  581.   }
  582.   return len;
  583. }
  584. /**
  585.  * Increment the reference count of the pbuf.
  586.  *
  587.  * @param p pbuf to increase reference counter of
  588.  *
  589.  */
  590. void
  591. pbuf_ref(struct pbuf *p)
  592. {
  593.   SYS_ARCH_DECL_PROTECT(old_level);
  594.   /* pbuf given? */
  595.   if (p != NULL) {
  596.     SYS_ARCH_PROTECT(old_level);
  597.     ++(p->ref);
  598.     SYS_ARCH_UNPROTECT(old_level);
  599.   }
  600. }
  601. /**
  602.  * Concatenate two pbufs (each may be a pbuf chain) and take over
  603.  * the caller's reference of the tail pbuf.
  604.  * 
  605.  * @note The caller MAY NOT reference the tail pbuf afterwards.
  606.  * Use pbuf_chain() for that purpose.
  607.  * 
  608.  * @see pbuf_chain()
  609.  */
  610. void
  611. pbuf_cat(struct pbuf *h, struct pbuf *t)
  612. {
  613.   struct pbuf *p;
  614.   LWIP_ASSERT("h != NULL (programmer violates API)", h != NULL);
  615.   LWIP_ASSERT("t != NULL (programmer violates API)", t != NULL);
  616.   if ((h == NULL) || (t == NULL)) return;
  617.   /* proceed to last pbuf of chain */
  618.   for (p = h; p->next != NULL; p = p->next) {
  619.     /* add total length of second chain to all totals of first chain */
  620.     p->tot_len += t->tot_len;
  621.   }
  622.   /* { p is last pbuf of first h chain, p->next == NULL } */
  623.   LWIP_ASSERT("p->tot_len == p->len (of last pbuf in chain)", p->tot_len == p->len);
  624.   LWIP_ASSERT("p->next == NULL", p->next == NULL);
  625.   /* add total length of second chain to last pbuf total of first chain */
  626.   p->tot_len += t->tot_len;
  627.   /* chain last pbuf of head (p) with first of tail (t) */
  628.   p->next = t;
  629.   /* p->next now references t, but the caller will drop its reference to t,
  630.    * so netto there is no change to the reference count of t.
  631.    */
  632. }
  633. /**
  634.  * Chain two pbufs (or pbuf chains) together.
  635.  * 
  636.  * The caller MUST call pbuf_free(t) once it has stopped
  637.  * using it. Use pbuf_cat() instead if you no longer use t.
  638.  * 
  639.  * @param h head pbuf (chain)
  640.  * @param t tail pbuf (chain)
  641.  * @note The pbufs MUST belong to the same packet.
  642.  * @note MAY NOT be called on a packet queue.
  643.  *
  644.  * The ->tot_len fields of all pbufs of the head chain are adjusted.
  645.  * The ->next field of the last pbuf of the head chain is adjusted.
  646.  * The ->ref field of the first pbuf of the tail chain is adjusted.
  647.  *
  648.  */
  649. void
  650. pbuf_chain(struct pbuf *h, struct pbuf *t)
  651. {
  652.   pbuf_cat(h, t);
  653.   /* t is now referenced by h */
  654.   pbuf_ref(t);
  655.   LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_chain: %p references %pn", (void *)h, (void *)t));
  656. }
  657. /* For packet queueing. Note that queued packets MUST be dequeued first
  658.  * using pbuf_dequeue() before calling other pbuf_() functions. */
  659. #if ARP_QUEUEING
  660. /**
  661.  * Add a packet to the end of a queue.
  662.  *
  663.  * @param q pointer to first packet on the queue
  664.  * @param n packet to be queued
  665.  *
  666.  * Both packets MUST be given, and must be different.
  667.  */
  668. void
  669. pbuf_queue(struct pbuf *p, struct pbuf *n)
  670. {
  671. #if PBUF_DEBUG /* remember head of queue */
  672.   struct pbuf *q = p;
  673. #endif
  674.   /* programmer stupidity checks */
  675.   LWIP_ASSERT("p == NULL in pbuf_queue: this indicates a programmer errorn", p != NULL);
  676.   LWIP_ASSERT("n == NULL in pbuf_queue: this indicates a programmer errorn", n != NULL);
  677.   LWIP_ASSERT("p == n in pbuf_queue: this indicates a programmer errorn", p != n);
  678.   if ((p == NULL) || (n == NULL) || (p == n)){
  679.     LWIP_DEBUGF(PBUF_DEBUG | DBG_HALT | 3, ("pbuf_queue: programmer argument errorn"))
  680.     return;
  681.   }
  682.   /* iterate through all packets on queue */
  683.   while (p->next != NULL) {
  684. /* be very picky about pbuf chain correctness */
  685. #if PBUF_DEBUG
  686.     /* iterate through all pbufs in packet */
  687.     while (p->tot_len != p->len) {
  688.       /* make sure invariant condition holds */
  689.       LWIP_ASSERT("p->len < p->tot_len", p->len < p->tot_len);
  690.       /* make sure each packet is complete */
  691.       LWIP_ASSERT("p->next != NULL", p->next != NULL);
  692.       p = p->next;
  693.       /* { p->tot_len == p->len => p is last pbuf of a packet } */
  694.     }
  695.     /* { p is last pbuf of a packet } */
  696.     /* proceed to next packet on queue */
  697. #endif
  698.     /* proceed to next pbuf */
  699.     if (p->next != NULL) p = p->next;
  700.   }
  701.   /* { p->tot_len == p->len and p->next == NULL } ==>
  702.    * { p is last pbuf of last packet on queue } */
  703.   /* chain last pbuf of queue with n */
  704.   p->next = n;
  705.   /* n is now referenced to by the (packet p in the) queue */
  706.   pbuf_ref(n);
  707. #if PBUF_DEBUG
  708.   LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2,
  709.     ("pbuf_queue: newly queued packet %p sits after packet %p in queue %pn",
  710.     (void *)n, (void *)p, (void *)q));
  711. #endif
  712. }
  713. /**
  714.  * Remove a packet from the head of a queue.
  715.  *
  716.  * The caller MUST reference the remainder of the queue (as returned). The
  717.  * caller MUST NOT call pbuf_ref() as it implicitly takes over the reference
  718.  * from p.
  719.  * 
  720.  * @param p pointer to first packet on the queue which will be dequeued.
  721.  * @return first packet on the remaining queue (NULL if no further packets).
  722.  *
  723.  */
  724. struct pbuf *
  725. pbuf_dequeue(struct pbuf *p)
  726. {
  727.   struct pbuf *q;
  728.   LWIP_ASSERT("p != NULL", p != NULL);
  729.   /* iterate through all pbufs in packet p */
  730.   while (p->tot_len != p->len) {
  731.     /* make sure invariant condition holds */
  732.     LWIP_ASSERT("p->len < p->tot_len", p->len < p->tot_len);
  733.     /* make sure each packet is complete */
  734.     LWIP_ASSERT("p->next != NULL", p->next != NULL);
  735.     p = p->next;
  736.   }
  737.   /* { p->tot_len == p->len } => p is the last pbuf of the first packet */
  738.   /* remember next packet on queue in q */
  739.   q = p->next;
  740.   /* dequeue packet p from queue */
  741.   p->next = NULL;
  742.   /* any next packet on queue? */
  743.   if (q != NULL) {
  744.     /* although q is no longer referenced by p, it MUST be referenced by
  745.      * the caller, who is maintaining this packet queue. So, we do not call
  746.      * pbuf_free(q) here, resulting in an implicit pbuf_ref(q) for the caller. */
  747.     LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_dequeue: first remaining packet on queue is %pn", (void *)q));
  748.   } else {
  749.     LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_dequeue: no further packets on queuen"));
  750.   }
  751.   return q;
  752. }
  753. #endif
  754. /**
  755.  *
  756.  * Create PBUF_POOL (or PBUF_RAM) copies of PBUF_REF pbufs.
  757.  *
  758.  * Used to queue packets on behalf of the lwIP stack, such as
  759.  * ARP based queueing.
  760.  *
  761.  * Go through a pbuf chain and replace any PBUF_REF buffers
  762.  * with PBUF_POOL (or PBUF_RAM) pbufs, each taking a copy of
  763.  * the referenced data.
  764.  *
  765.  * @note You MUST explicitly use p = pbuf_take(p);
  766.  * The pbuf you give as argument, may have been replaced
  767.  * by a (differently located) copy through pbuf_take()!
  768.  *
  769.  * @note Any replaced pbufs will be freed through pbuf_free().
  770.  * This may deallocate them if they become no longer referenced.
  771.  *
  772.  * @param p Head of pbuf chain to process
  773.  *
  774.  * @return Pointer to head of pbuf chain
  775.  */
  776. struct pbuf *
  777. pbuf_take(struct pbuf *p)
  778. {
  779.   struct pbuf *q , *prev, *head;
  780.   LWIP_ASSERT("pbuf_take: p != NULLn", p != NULL);
  781.   LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_take(%p)n", (void*)p));
  782.   prev = NULL;
  783.   head = p;
  784.   /* iterate through pbuf chain */
  785.   do
  786.   {
  787.     /* pbuf is of type PBUF_REF? */
  788.     if (p->flags == PBUF_FLAG_REF) {
  789.       LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE, ("pbuf_take: encountered PBUF_REF %pn", (void *)p));
  790.       /* allocate a pbuf (w/ payload) fully in RAM */
  791.       /* PBUF_POOL buffers are faster if we can use them */
  792.       if (p->len <= PBUF_POOL_BUFSIZE) {
  793.         q = pbuf_alloc(PBUF_RAW, p->len, PBUF_POOL);
  794.         if (q == NULL) {
  795.           LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_take: Could not allocate PBUF_POOLn"));
  796.         }
  797.       } else {
  798.         /* no replacement pbuf yet */
  799.         q = NULL;
  800.         LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_take: PBUF_POOL too small to replace PBUF_REFn"));
  801.       }
  802.       /* no (large enough) PBUF_POOL was available? retry with PBUF_RAM */
  803.       if (q == NULL) {
  804.         q = pbuf_alloc(PBUF_RAW, p->len, PBUF_RAM);
  805.         if (q == NULL) {
  806.           LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 2, ("pbuf_take: Could not allocate PBUF_RAMn"));
  807.         }
  808.       }
  809.       /* replacement pbuf could be allocated? */
  810.       if (q != NULL)
  811.       {
  812.         /* copy p to q */
  813.         /* copy successor */
  814.         q->next = p->next;
  815.         /* remove linkage from original pbuf */
  816.         p->next = NULL;
  817.         /* remove linkage to original pbuf */
  818.         if (prev != NULL) {
  819.           /* prev->next == p at this point */
  820.           LWIP_ASSERT("prev->next == p", prev->next == p);
  821.           /* break chain and insert new pbuf instead */
  822.           prev->next = q;
  823.         /* prev == NULL, so we replaced the head pbuf of the chain */
  824.         } else {
  825.           head = q;
  826.         }
  827.         /* copy pbuf payload */
  828.         memcpy(q->payload, p->payload, p->len);
  829.         q->tot_len = p->tot_len;
  830.         q->len = p->len;
  831.         /* in case p was the first pbuf, it is no longer refered to by
  832.          * our caller, as the caller MUST do p = pbuf_take(p);
  833.          * in case p was not the first pbuf, it is no longer refered to
  834.          * by prev. we can safely free the pbuf here.
  835.          * (note that we have set p->next to NULL already so that
  836.          * we will not free the rest of the chain by accident.)
  837.          */
  838.         pbuf_free(p);
  839.         /* do not copy ref, since someone else might be using the old buffer */
  840.         LWIP_DEBUGF(PBUF_DEBUG, ("pbuf_take: replaced PBUF_REF %p with %pn", (void *)p, (void *)q));
  841.         p = q;
  842.       } else {
  843.         /* deallocate chain */
  844.         pbuf_free(head);
  845.         LWIP_DEBUGF(PBUF_DEBUG | 2, ("pbuf_take: failed to allocate replacement pbuf for %pn", (void *)p));
  846.         return NULL;
  847.       }
  848.     /* p->flags != PBUF_FLAG_REF */
  849.     } else {
  850.       LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 1, ("pbuf_take: skipping pbuf not of type PBUF_REFn"));
  851.     }
  852.     /* remember this pbuf */
  853.     prev = p;
  854.     /* proceed to next pbuf in original chain */
  855.     p = p->next;
  856.   } while (p);
  857.   LWIP_DEBUGF(PBUF_DEBUG | DBG_TRACE | 1, ("pbuf_take: end of chain reached.n"));
  858.   return head;
  859. }
  860. /**
  861.  * Dechains the first pbuf from its succeeding pbufs in the chain.
  862.  *
  863.  * Makes p->tot_len field equal to p->len.
  864.  * @param p pbuf to dechain
  865.  * @return remainder of the pbuf chain, or NULL if it was de-allocated.
  866.  * @note May not be called on a packet queue.
  867.  */
  868. struct pbuf *
  869. pbuf_dechain(struct pbuf *p)
  870. {
  871.   struct pbuf *q;
  872.   u8_t tail_gone = 1;
  873.   /* tail */
  874.   q = p->next;
  875.   /* pbuf has successor in chain? */
  876.   if (q != NULL) {
  877.     /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */
  878.     LWIP_ASSERT("p->tot_len == p->len + q->tot_len", q->tot_len == p->tot_len - p->len);
  879.     /* enforce invariant if assertion is disabled */
  880.     q->tot_len = p->tot_len - p->len;
  881.     /* decouple pbuf from remainder */
  882.     p->next = NULL;
  883.     /* total length of pbuf p is its own length only */
  884.     p->tot_len = p->len;
  885.     /* q is no longer referenced by p, free it */
  886.     LWIP_DEBUGF(PBUF_DEBUG | DBG_STATE, ("pbuf_dechain: unreferencing %pn", (void *)q));
  887.     tail_gone = pbuf_free(q);
  888.     if (tail_gone > 0) {
  889.       LWIP_DEBUGF(PBUF_DEBUG | DBG_STATE,
  890.                   ("pbuf_dechain: deallocated %p (as it is no longer referenced)n", (void *)q));
  891.     }
  892.     /* return remaining tail or NULL if deallocated */
  893.   }
  894.   /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */
  895.   LWIP_ASSERT("p->tot_len == p->len", p->tot_len == p->len);
  896.   return (tail_gone > 0? NULL: q);
  897. }