lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] pbuf question


From: Leon Woestenberg
Subject: Re: [lwip-users] pbuf question
Date: Sun, 11 Jul 2004 02:55:59 +0200
User-agent: Mozilla Thunderbird 0.7.1 (Windows/20040626)

Hello Tim,

please read pbuf.c function inline documentation and also pbuf.h structure inline documentation.

I think what you need is the pbuf_cat() function.

But to lay down some understanding:

The "ref" counter counts how many pointer references there are to that pbuf.

given
(pbuf1->ref, pbuf1->next->ref) = (1,1)
(pbuf2->ref, pbuf2->next->ref) = (1,1)

and then calling pbuf_chain(pbuf1, pbuf2) will indeed result in

(pbuf1->ref, pbuf1->next->ref, pbuf1->next->next->ref, pbuf1->next->next->next->ref) = (1,1,2,1)

as lwIP thinks there is one pointer to the first pbuf (namely "pbuf1"), one pointer to the second pbuf (namely "pbuf1->next"), two pointers to the third pbuf (namely "pbuf1->next->next" and "pbuf2")
and one pointer to the fourth pbuf (namely "pbuf1->next->next->next").

When your application chains the two pbufs, and releases its pointer reference to the second, it should call pbuf_free(pbuf2) to inform lwIP on the released pointer, just like Jim Gibbons deduced and described correctly (see below). But pbuf_cat() is more optimal in that case.

pbuf_cat(pbuf1, pbuf2) explicitly assumes that you release the pbuf2 pointer (i.e. no longer use it).

BTW, to easen debugging, you should really do a pbuf2 = NULL; right after your call to pbuf_cat(...,pbuf2)
or pbuf_free(pbuf2).

Jim Gibbons wrote:

If you look in tcp_in.c, in tcp_receive, you will find a call to pbuf_chain that seems analogous to yours. It is followed by a call to pbuf_free, which undoes the ref increment in pbuf_chain. In fact, when I scanned the code in core, I found that every pbuf_chain call was followed immediately by a pbuf_free. I have to agree that this situation does make it seem that perhaps the operations of the pbuf chain and queue functions aren't as convenient to the caller as they might be.

In defense of the way things are, however, the caller of pbuf_chain is still in possession of both of the pbuf pointers upon return. It isn't clear (to pbuf_chain) whether the caller will abandon the one that has been attached to the chain or continue to use it. The pbuf_free call after pbuf_chain makes this clear, though perhaps at the cost of efficiency.

Side-note about "the slight cost of efficiency": This was discussed on the lwip-devel list earlier, but we really needed an orthogonal pbuf_chain() and pbuf_free() for some implementation reason I do not recall at this
point.

pbuf_cat() is optimal
pbuf_chain() is just a pbuf_cat(); pbuf_ref().
pbuf_chain(); pbuf_free() is equal to pbuf_cat(); pbuf_ref(); pbuf_free()

pbuf_ref(); pbuf_free() is the unwanted overhead (which is a no-op).

Regards,

Leon.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]