Extending sbufs with a drain

Poul-Henning Kamp phk at phk.freebsd.dk
Wed Sep 8 17:38:46 UTC 2010


In message <AANLkTikd=_6=7-P6-qhNkCN+u723J6WYGiD2NnPDsWFO at mail.gmail.com>, mdf@
FreeBSD.org writes:


>I don't object to adding drains to userland.  I want to. 

Cool, no disagreement there then.

>I would assume that, if someone really wants this is userland before I
>can get to this (and it is on my list of desired things to do) then
>they can write the code first.

...or you make the simple interrim implementation that mandates that
the buffer is big enough for any single operation performed on the
sbuf (and overflow if it was not).  In userland it is pretty much
gratis to allocate a huge buffer, thanks to the wonder of Virtual
Memory and JEmalloc.

>> Which bit of "errno not relevant" in the description of -2 did
>> you fail to notice ? =A0:-)
>
>Well, the specific error code is relevant, and I don't really want an
>sbuf_set_error() function.  For example, if my drain function is
>SYSCTL_OUT, I want to preserve the error code that returned.

Yeah, I guess for the kernel we may have to make the return
-errno to allow that capture.  Consider my prototype proposal
changed as such:  >= 0 # bytes flushed, <0 = -errno.

>> Yes, but why would you want to ? =A0Normally private arguments are typed
>> "void *" as they more often than not point to some structure, to
>> which you can cast a void* directly, whereas uintptr_t requires a
>> explicit cast.
>
>If my drain function is in userspace and writes to a file descriptor
>I'd want it.

Which is then the exceptional case where you would then have to cast it
past a uintptr_t.  The convention in all our code is that private
arguments are void*, because that is generally the easiest to deal
with, and we should stick to that.

>Autoextend did not dictate the drain prototype.  The autoextend drain
>*is* an sbuf internal function -- note its existence in subr_sbuf.c.

Yes it did.  Any other drain function can be implemented with the prototype
I provided you with.  Only autoextend has a unavoidable need to fondle
the sbuf internals.  No other drain function will ever need to.

>There may be other desired uses for a drain that don't just print to a
>file/console/log, though those are the most likely.

See the previously cited Gettys quote.

You can always pass the necessary context through the private pointer,
but you will never have a legitimate need to fondle the sbufs internals.


And now for the tough one:

>In the end I would like a One True Printf to bind them all[...]

You and me brother, amen!

I don't think an OTP is possible without compiler and language
support, and since the ISO-C people seems to have evaded this desire
to the full extent of their ability, it is probably never going
to happen in the C language.

For one thing a OTP would allow you to define type specific formatters,
sort of the way the chapter 1. example in any C++ book teaches with
the << operator.  But this would require passing not only the varargs
but also their types to the formatting function.

It would be trivial for the compiler to insert a type specifying
enum/bitmap before every argument, so that printf and any other
varargs using functions knew what it was dealing with.  I kind of
like this idea, as it basically makes varargs typesafe, but obviously
ISO-C think it is not kosher.

However, this has nothing to do with the patches we are discussing,
because they do not implement our desired OTP.

As I said, I agree about the usefulness, and with a API that fits
the sbuf design, I can probably be persuaded.

But I will always have this nagging doubt that we just added yet
another deadbeat extension, rather than actually solve the
actual problem.

Poul-Henning

-- 
Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
phk at FreeBSD.ORG         | TCP/IP since RFC 956
FreeBSD committer       | BSD since 4.3-tahoe    
Never attribute to malice what can adequately be explained by incompetence.


More information about the freebsd-arch mailing list