mailing list of musl libc
 help / color / mirror / code / Atom feed
From: Rich Felker <dalias@libc.org>
To: musl@lists.openwall.com
Subject: Re: Stdio resource usage
Date: Thu, 21 Feb 2019 12:02:59 -0500	[thread overview]
Message-ID: <20190221170259.GH23599@brightrain.aerifal.cx> (raw)
In-Reply-To: <20190221160937.GF19969@voyager>

On Thu, Feb 21, 2019 at 05:09:37PM +0100, Markus Wichmann wrote:
> On Wed, Feb 20, 2019 at 02:24:23PM -0500, Rich Felker wrote:
> > For what it's worth, gcc has a -fconserve-stack that in principle
> > should avoid this problem, but I could never get it to do anything. If
> > it works now we should probably detect and add it to default CFLAGS.
> > 
> > Rich
> 
> Well, that also doesn't help since gcc is the compiler that *doesn't*
> exhibit the problem. clang does. And clang doesn't have an option to
> conserve stack (that I've seen).
> 
> I am wondering what other possibilities exist to prevent the issue. If
> we won't change the algorithm, that only leaves exploring other
> possibilities for the memory allocation.

There is no algorithm that takes less space, at not without some kind
of cubic-in-exponent-value or worse time. The amount of space we use
is optimal up to some small factor. It might be possible to shrink
this factor with a sharper bound on number of digits needed, with no
change in the algorihm, but I think the reduction would be at most
something like 20%.

> So, what are our choices?
> 
> - Heap allocation: But that can fail. Now, printf() is actually allowed
>   to fail, but no-one expects it to. I would expect such behavior to be
>   problematic at best.

printf can fail for valid reasons, but snprintf cannot. Technically
POSIX allows any interface that can fail to be able to fail for
additional implementation-defined reasons, but this is unacceptably
bad QoI and completely contrary to the principles of musl, that
nothing fails unless there's an underlying reason it has to be able to
fail.

> - Static allocation: Without synchronization this won't be thread-safe,
>   with synchronization it won't be re-entrant. Now, as far as I could
>   see, the printf() family is actually not required to be re-entrant
>   (e.g. signal-safety(7) fails to list any of them), but I have seen
>   sprintf() in signal handlers in the wild (well, exception handlers,
>   really).

If you can afford to increase .data size by ~8k, why can'd you just
increase stack size by ~8k instead? Of course the latter would scale
in number of threads, but presumably if you're this
resource-constrained you're not using threads, or can avoid using
printf from most of them.

> - Thread-local static allocation: Which is always a hassle in libc, and
>   does not take care of re-entrancy. It would only solve the
>   thread-safety issue.

This is strictly-worse than just using the stack. Implementation-wise,
the TLS is equivalent to a stack object on the top-level call frame of
the thread. There's no reason to put it there rather than in the
bottom-level call frame.

> - As-needed stack allocation (e.g. alloca()): This fails to prevent the
>   worst case allocation, though it would make the average allocation
>   more bearable. But I don't know if especially clever compilers like
>   clang wouldn't optimize this stuff away, and we'd be back to square
>   one.

This is what I already suggested (via VLA, not alloca, as the latter
is not C and worse in most ways) as a workaround for the clang
hoisting of allocations. But in principle the compiler could still see
that if the declaration is reachable the size is constant (or even
close enough to constant that it could just optimize to a fixed-size
array of the upper bound), and optimize out its being variable, then
hoist it. So this really is a hack that's "tricking the optimizer",
not any fundamental fix.

> Any ideas left?

Getting clang to fix their hoisting of (large) stack objects beyond
their scope/lifetime?

Rich


      parent reply	other threads:[~2019-02-21 17:02 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-19 23:34 Nick Bray
2019-02-20  2:43 ` Rich Felker
2019-02-20 10:49   ` Szabolcs Nagy
2019-02-20 15:47     ` Markus Wichmann
2019-02-20 16:37       ` Szabolcs Nagy
2019-02-20 17:13         ` Rich Felker
2019-02-20 18:34       ` A. Wilcox
2019-02-20 19:11         ` Markus Wichmann
2019-02-20 19:24           ` Rich Felker
2019-02-21 16:09             ` Markus Wichmann
2019-02-21 16:27               ` Jens Gustedt
2019-02-21 17:02               ` Rich Felker [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190221170259.GH23599@brightrain.aerifal.cx \
    --to=dalias@libc.org \
    --cc=musl@lists.openwall.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).