[PATCH v3] Make fprintf() function to multithread-safe
Rich Felker
dalias@aerifal.cx
Tue Jul 24 01:39:00 GMT 2012
On Mon, Jul 23, 2012 at 08:57:56PM -0400, Carlos O'Donell wrote:
> On Tue, Jul 10, 2012 at 5:18 AM, Roland McGrath <roland@hack.frob.com> wrote:
> > There is no need to target individuals in your email.
> > Just post to the list.
> >
> > Please file a bugzilla report for this issue.
> >
> > I am not at all sanguine about taking any global locks in vfprintf,
> > even a reader lock. It is a code path that is extremely common and
> > often performance-critical. Conversely, register_printf_specifier
> > et al are called very rarely and their performance never matters much.
> >
> > I think it's worth investigating an alternative approach where
> > changes work by allocating a new table and replacing the old one
> > with atomic operations. There is complexity there about tracking
> > when it's safe to free the old table, so it's not a trivial change.
> >
> > Perhaps the reader locks are in fact just as efficient (for the
> > reader) as anything that could be done with the atomic-supersede
> > style. But I think it merits some real investigation and concrete
> > performance analysis.
>
> I agree with Roland here.
>
> We need to see some real investigation and performance analysis.
>
> Making fprintf multithread-safe is important, but we should not do
> so using a heavy hammer approach involving global locks.
>
> Do you have any workloads that you can use for performance testing?
I'm rather unconvinced there's an issue here. The situation is similar
to locale, where functions (like printf) that depend on locale are not
safe to call during setlocale (this is why uselocale was added).
Unlike locale and the need for uselocale, however, I can't think of a
good argument that adding custom printf format specifiers after
startup would be needed.
The most likely _candidate_ usage case would be when the format
specifier is registered from a constructor or explicit init function
in a library that's loaded with dlopen rather than at program startup.
But is it really reasonable design for libraries to be registering
printf specifiers anyway?
What I'd really prefer to see is for this entire functionality to be
deprecated, and if it's really needed, replaced by an equivalent
mechanism without global state in the form:
printf("%Q", custom_format_object, my_data);
where custom_format_object is either a pointer to a caller-filled
structure of an opaque pointer obtained by a function to allocate a
new printf custom formatting, and "%Q" is a random letter I made up to
indicate to printf that it should expect such a pointer followed by a
pointer to the actual data.
This would be entirely stateless, would not run into a limit on the
number of custom formats, and would not have libraries stepping on
each other if/when they try to use it.
With that said, I question the value of the whole thing. It seems a
lot more reasonable to just have your custom data types provide a
convert-to-string method that can then be passed as the argument with
a %s specifier without relying on non-portable GNU printf extensions.
Rich
More information about the Libc-alpha
mailing list