Extending sbufs with a drain

mdf at FreeBSD.org mdf at FreeBSD.org
Wed Sep 8 17:51:47 UTC 2010


Adding info to the quasi-digression:

> 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.

One other thing we have at Isilon that I would like to find some way
to add to FreeBSD is the generic printf specifier.

We added support in gcc for a %{} printf specifier which takes a
struct fmt_conv_ctx:

/** One of these gets passed to fmt_print for each %{}. */
struct fmt_conv_ctx {
        fmt_conv_func           func;
        union fmt_conv_arg      arg;
};

where the fmt_conv_func is:

/** Specifies the type of format conversion function. */
typedef void (*fmt_conv_func)(struct fmt *, const struct fmt_conv_args *,
    union fmt_conv_arg);

and the fmt_conv_arg is a union of 2 uint64s, 2 pointers, 2 ints, a
pointer and size_t, etc., etc.  I.e. a generic blob that can hold a
little data, or a pointer to a big thing.  The fmt_conv_args has the
bits indicating all the format modifiers like precision, left
justification, etc., and also any string that appeared between { and
}.

Then when fmt_printf sees the %{} format it calls the function to add
to the current struct fmt.  Since it's unknown how long the %{} format
data may end up being (and in fact a specifier to print a struct may
use %{} on various members), there's a need for expanding the buffer
or draining it.

This is the glorious part 2, but I can easily see there's a *lot* of
room for architecting a better solution.  This is just what we have in
house.

> 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.

So just to clarify, what do you consider the actual problem?

I can say for sure that we have a lot of internal uses of out struct
fmt (the thing we rolled before sbuf existed, that either grows or
drains depending on initialization).  There's a fine-grained leveled
logging system, our ASSERT macro uses it.  We use fmt_print() for all
our sysctl handlers that deal with outputting text.  The only things
that don't anymore internally are the original printf(), panic() and
KASSERT, and our code base has not added any more uses of those since
it doesn't have the various print formatters we wanted.

If preferred, I can start with a patch that adds %{} support to kernel
and user printf implementations, but as I say the interface we use
internally may not be preferred.

Thanks,
matthew


More information about the freebsd-arch mailing list