/[lwip]/lwip/src/core/pbuf.c
ViewVC logotype

Diff of /lwip/src/core/pbuf.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.36 by likewise, Tue Apr 1 09:35:20 2003 UTC revision 1.37 by likewise, Tue Apr 1 12:17:55 2003 UTC
# Line 236  pbuf_alloc(pbuf_layer l, u16_t length, p Line 236  pbuf_alloc(pbuf_layer l, u16_t length, p
236    offset = 0;    offset = 0;
237    switch (l) {    switch (l) {
238    case PBUF_TRANSPORT:    case PBUF_TRANSPORT:
239        /* add room for transport (often TCP) layer header */
240      offset += PBUF_TRANSPORT_HLEN;      offset += PBUF_TRANSPORT_HLEN;
241      /* FALLTHROUGH */      /* FALLTHROUGH */
242    case PBUF_IP:    case PBUF_IP:
243        /* add room for IP layer header */
244      offset += PBUF_IP_HLEN;      offset += PBUF_IP_HLEN;
245      /* FALLTHROUGH */      /* FALLTHROUGH */
246    case PBUF_LINK:    case PBUF_LINK:
247        /* add room for link layer header */
248      offset += PBUF_LINK_HLEN;      offset += PBUF_LINK_HLEN;
249      break;      break;
250    case PBUF_RAW:    case PBUF_RAW:
# Line 263  pbuf_alloc(pbuf_layer l, u16_t length, p Line 266  pbuf_alloc(pbuf_layer l, u16_t length, p
266      }      }
267      p->next = NULL;      p->next = NULL;
268            
269      /* make the payload pointer point offset bytes into pbuf data memory */      /* make the payload pointer point 'offset' bytes into pbuf data memory */
270      p->payload = MEM_ALIGN((void *)((u8_t *)p + (sizeof(struct pbuf) + offset)));      p->payload = MEM_ALIGN((void *)((u8_t *)p + (sizeof(struct pbuf) + offset)));
271      /* the total length of the pbuf is the requested size */      LWIP_ASSERT("pbuf_alloc: pbuf p->payload properly aligned",
272                ((u32_t)p->payload % MEM_ALIGNMENT) == 0);
273        /* the total length of the pbuf chain is the requested size */
274      p->tot_len = length;      p->tot_len = length;
275      /* set the length of the first pbuf in the chain */      /* set the length of the first pbuf in the chain */
276      p->len = length > PBUF_POOL_BUFSIZE - offset? PBUF_POOL_BUFSIZE - offset: length;      p->len = length > PBUF_POOL_BUFSIZE - offset? PBUF_POOL_BUFSIZE - offset: length;
277        /* set pbuf type */
278      p->flags = PBUF_FLAG_POOL;      p->flags = PBUF_FLAG_POOL;
279            
280      /* allocate the tail of the pbuf chain. */      /* now allocate the tail of the pbuf chain */
281        
282        /* remember first pbuf for linkage in next iteration */
283      r = p;      r = p;
284      /* remaining length to be allocated */      /* remaining length to be allocated */
285      rem_len = length - p->len;      rem_len = length - p->len;
# Line 279  pbuf_alloc(pbuf_layer l, u16_t length, p Line 287  pbuf_alloc(pbuf_layer l, u16_t length, p
287      while(rem_len > 0) {            while(rem_len > 0) {      
288        q = pbuf_pool_alloc();        q = pbuf_pool_alloc();
289        if (q == NULL) {        if (q == NULL) {
290          DEBUGF(PBUF_DEBUG | 2, ("pbuf_alloc: Out of pbufs in pool.\n"));         DEBUGF(PBUF_DEBUG | 2, ("pbuf_alloc: Out of pbufs in pool.\n"));
291  #ifdef PBUF_STATS  #ifdef PBUF_STATS
292          ++lwip_stats.pbuf.err;          ++lwip_stats.pbuf.err;
293  #endif /* PBUF_STATS */  #endif /* PBUF_STATS */
# Line 287  pbuf_alloc(pbuf_layer l, u16_t length, p Line 295  pbuf_alloc(pbuf_layer l, u16_t length, p
295          pbuf_pool_free(p);          pbuf_pool_free(p);
296          return NULL;          return NULL;
297        }        }
298        q->next = NULL;        //q->next = NULL;
299          /* make previous pbuf point to this pbuf */
300        r->next = q;        r->next = q;
301          /* set length of this pbuf */
302        q->len = rem_len > PBUF_POOL_BUFSIZE? PBUF_POOL_BUFSIZE: rem_len;        q->len = rem_len > PBUF_POOL_BUFSIZE? PBUF_POOL_BUFSIZE: rem_len;
303        q->flags = PBUF_FLAG_POOL;        q->flags = PBUF_FLAG_POOL;
304        q->payload = (void *)((u8_t *)q + sizeof(struct pbuf));        q->payload = (void *)((u8_t *)q + sizeof(struct pbuf));
305        r = q;        LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned",
306                  ((u32_t)q->payload % MEM_ALIGNMENT) == 0);
307        q->ref = 1;        q->ref = 1;
308          /* calculate remaining length to be allocated */
309        rem_len -= q->len;        rem_len -= q->len;
310          /* remember this pbuf for linkage in next iteration */
311          r = q;
312      }      }
313      /* end of chain */      /* end of chain */
314      r->next = NULL;      r->next = NULL;
315    
     LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned",  
            ((u32_t)p->payload % MEM_ALIGNMENT) == 0);  
316      break;      break;
317    case PBUF_RAM:    case PBUF_RAM:
318      /* If pbuf is to be allocated in RAM, allocate memory for it. */      /* If pbuf is to be allocated in RAM, allocate memory for it. */
# Line 486  pbuf_realloc(struct pbuf *p, u16_t new_l Line 498  pbuf_realloc(struct pbuf *p, u16_t new_l
498  }  }
499    
500  /**  /**
501   * Adjusts the payload pointer +/- for header.   * Adjusts the payload pointer to hide or reveal headers in the payload.
502   *   *
503   * Adjusts the ->payload pointer so that space for a header appears in   * Adjusts the ->payload pointer so that space for a header
504   * the pbuf. Also, the ->tot_len and ->len fields are adjusted.   * (dis)appears in the pbuf payload.
505     *
506     * The ->payload, ->tot_len and ->len fields are adjusted.
507   *   *
508   * @param hdr_size Number of bytes to increment header size which   * @param hdr_size Number of bytes to increment header size which
509   * increases the size of the pbuf. New space is on the front.   * increases the size of the pbuf. New space is on the front.
# Line 543  pbuf_header(struct pbuf *p, s16_t header Line 557  pbuf_header(struct pbuf *p, s16_t header
557  }  }
558    
559  /**  /**
560   * Free a pbuf (chain) from its user, de-allocate if zero users.   * Free a pbuf (chain) from usage, de-allocate non-used head of chain.
561   *   *
562   * Decrements the pbuf reference count. If it reaches   * Decrements the pbuf reference count. If it reaches
563   * zero, the pbuf is deallocated.   * zero, the pbuf is deallocated.
564   *   *
565   * This is repeated for each pbuf in the chain, until a non-zero   * For a pbuf chain, this is repeated for each pbuf in the chain, until
566   * reference count is encountered, or the end of the chain is reached.   * a non-zero reference count is encountered, or the end of the chain is
567     * reached.
568   *   *
569   * @param pbuf pbuf (chain) to be freed from its user.   * @param pbuf pbuf (chain) to be freed from one user.
570   *   *
571   * @return the number of unreferenced pbufs that were de-allocated   * @return the number of unreferenced pbufs that were de-allocated
572   * from the head of the chain.   * from the head of the chain.
# Line 714  pbuf_chain(struct pbuf *h, struct pbuf * Line 729  pbuf_chain(struct pbuf *h, struct pbuf *
729      /* add total length of second chain to all totals of first chain */      /* add total length of second chain to all totals of first chain */
730      p->tot_len += t->tot_len;      p->tot_len += t->tot_len;
731    }    }
732      /* p is last pbuf of first h chain */
733    /* add total length of second chain to last pbuf total of first chain */    /* add total length of second chain to last pbuf total of first chain */
734    p->tot_len += t->tot_len;    p->tot_len += t->tot_len;
735    /* chain last pbuf of h chain (p) with first of tail (t) */    /* chain last pbuf of h chain (p) with first of tail (t) */
# Line 748  pbuf_dechain(struct pbuf *p) Line 764  pbuf_dechain(struct pbuf *p)
764      /* total length of pbuf p is its own length only */      /* total length of pbuf p is its own length only */
765      p->tot_len = p->len;      p->tot_len = p->len;
766      /* q is no longer referenced by p, free it */      /* q is no longer referenced by p, free it */
767      DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_dechain: unreferencing %p\n", (void *) q));      DEBUGF(PBUF_DEBUG | DBG_STATE, ("pbuf_dechain: unreferencing %p\n", (void *) q));
768      tail_gone = pbuf_free(q);      tail_gone = pbuf_free(q);
769      /* return remaining tail or NULL if deallocated */      /* return remaining tail or NULL if deallocated */
770    }    }
# Line 765  pbuf_dechain(struct pbuf *p) Line 781  pbuf_dechain(struct pbuf *p)
781   * with PBUF_POOL (or PBUF_RAM) pbufs, each taking a copy of   * with PBUF_POOL (or PBUF_RAM) pbufs, each taking a copy of
782   * the referenced data.   * the referenced data.
783   *   *
784   * @note The pbuf you give as argument, may have been replaced   * @note You MUST explicitly use p = pbuf_take(p);
785   * by calling pbuf_take(p). You must therefore explicitly use   * The pbuf you give as argument, may have been replaced
786   * p = pbuf_take(p);   * by pbuf_take()!
787     *
788   * @note Any replaced pbufs will be freed through pbuf_free().   * @note Any replaced pbufs will be freed through pbuf_free().
789   *   *
790   * Used to queue packets on behalf of the lwIP stack, such as   * Used to queue packets on behalf of the lwIP stack, such as
# Line 775  pbuf_dechain(struct pbuf *p) Line 792  pbuf_dechain(struct pbuf *p)
792   *   *
793   * @param f Head of pbuf chain to process   * @param f Head of pbuf chain to process
794   *   *
795   * @return Pointer to new head of pbuf chain (which may have been   * @return Pointer to new head of pbuf chain
  * replaced itself).  
796   */   */
797  struct pbuf *  struct pbuf *
798  pbuf_take(struct pbuf *f)  pbuf_take(struct pbuf *f)
799  {  {
800    struct pbuf *p, *prev, *top;    struct pbuf *p, *prev, *top;
801    LWIP_ASSERT("pbuf_take: f != NULL", f != NULL);    LWIP_ASSERT("pbuf_take: f != NULL\n", f != NULL);
802    DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_take(%p)\n", (void*)f));    DEBUGF(PBUF_DEBUG | DBG_TRACE | 3, ("pbuf_take(%p)\n", (void*)f));
803    
804    prev = NULL;    prev = NULL;
# Line 814  pbuf_take(struct pbuf *f) Line 830  pbuf_take(struct pbuf *f)
830        }        }
831        /* replacement pbuf could be allocated? */        /* replacement pbuf could be allocated? */
832        if (q != NULL)        if (q != NULL)
833        {          {
834            /* copy p to q */  
835          /* copy successor */          /* copy successor */
836          q->next = p->next;          q->next = p->next;
837          /* remove linkage from original pbuf */          /* remove linkage from original pbuf */
# Line 825  pbuf_take(struct pbuf *f) Line 842  pbuf_take(struct pbuf *f)
842            /* break chain and insert new pbuf instead */            /* break chain and insert new pbuf instead */
843            prev->next = q;            prev->next = q;
844          /* prev == NULL, so we replaced the top pbuf of the chain */          /* prev == NULL, so we replaced the top pbuf of the chain */
845          } else          } else {
846            top = q;            top = q;
847            }
848          /* copy pbuf payload */          /* copy pbuf payload */
849          memcpy(q->payload, p->payload, p->len);          memcpy(q->payload, p->payload, p->len);
850          q->tot_len = p->tot_len;          q->tot_len = p->tot_len;
851          q->len = p->len;          q->len = p->len;
852            /* in case p was the first pbuf, it is no longer refered to by
853             * our caller, as the caller MUST do p = pbuf_take(p);
854             * in case p was not the first pbuf, it is no longer refered to
855             * by prev. we can safely free the pbuf here.
856             * (note that we have set p->next to NULL already so that
857             * we will not free the rest of the chain by accident.)
858             */
859            pbuf_free(p);
860          /* do not copy ref, since someone else might be using the old buffer */          /* do not copy ref, since someone else might be using the old buffer */
         /* pbuf is not freed, as this is the responsibility of the application */  
861          DEBUGF(PBUF_DEBUG, ("pbuf_take: replaced PBUF_REF %p with %p\n", (void *)p, (void *)q));          DEBUGF(PBUF_DEBUG, ("pbuf_take: replaced PBUF_REF %p with %p\n", (void *)p, (void *)q));
862          /* p is no longer pointed to by prev or by our caller,          /* p is no longer pointed to by prev or by our caller,
863           * as the caller must do p = pbuf_take(p); so free it           * as the caller must do p = pbuf_take(p); so free it
# Line 848  pbuf_take(struct pbuf *f) Line 873  pbuf_take(struct pbuf *f)
873          DEBUGF(PBUF_DEBUG | 2, ("pbuf_take: failed to allocate replacement pbuf for %p\n", (void *)p));          DEBUGF(PBUF_DEBUG | 2, ("pbuf_take: failed to allocate replacement pbuf for %p\n", (void *)p));
874          return NULL;          return NULL;
875        }        }
876        /* p->flags != PBUF_FLAG_REF */
877        } else {
878          DEBUGF(PBUF_DEBUG | DBG_TRACE | 1, ("pbuf_take: skipping pbuf not of type PBUF_REF\n"));
879      }      }
880      else {      /* remember this pbuf */
       DEBUGF(PBUF_DEBUG | DBG_TRACE | 1, ("pbuf_take: not PBUF_REF\n"));  
     }  
   
881      prev = p;      prev = p;
882        /* proceed to next pbuf in original chain */
883      p = p->next;      p = p->next;
884    } while (p);    } while (p);
885    DEBUGF(PBUF_DEBUG | DBG_TRACE | 1, ("pbuf_take: end of chain reached.\n"));    DEBUGF(PBUF_DEBUG | DBG_TRACE | 1, ("pbuf_take: end of chain reached.\n"));

Legend:
Removed from v.1.36  
changed lines
  Added in v.1.37

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26