Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date: Sun, 31 Aug 2014 20:04:23 -0400
From: Rich Felker <dalias@...c.org>
To: musl@...ts.openwall.com
Subject: Re: [PATCH 7/8] add the thrd_xxxxxx functions

On Sun, Aug 31, 2014 at 09:10:46PM +0200, Jens Gustedt wrote:
> Am Sonntag, den 31.08.2014, 13:02 -0400 schrieb Rich Felker:
> > On Sun, Aug 31, 2014 at 06:36:00PM +0200, Jens Gustedt wrote:
> > > EAGAIN from clone is clearly a distinct error condition than when it
> > > is on ENOMEM. I would not see it covered by what C11 expects as that
> > > error condition. So the EAGAIN from clone should go to thrd_error, I
> > > think, and not be merged with ENOMEM for the C threads implementation.
> > 
> > I disagree here, at least unless you have a convincing argument for
> > this. EAGAIN from clone reflects a condition where a resource could
> > not be allocated. The reason (policy or inherent limits on a
> > particular type of resource, as opposed to just generally running out
> > of memory) doesn't seem to be relevant to applications, and I don't
> > see how thrd_error is any more appropriate than thrd_nomem for
> > reporting it. Certainly there are other cases where one type of
> > allocation (e.g. mmap for a thread) might fail where another (e.g.
> > malloc reusing freed memory on the heap) might fail, so I don't think
> > you can say that thrd_nomem is inappropriate if malloc would succeed.
> 
> The convincing arguments come from the documentation, I'd say. C11
> says
> 
>   The thrd_create function returns
> 
>    thrd_success on success, or
> 
>    thrd_nomem if no memory could be allocated for the thread requested, or
> 
>    thrd_error if the request could not be honored.
> 
> (If this is a reasonable distinction of errors is a completely
> different question.)
> 
> The man page for clone (whatever authority this has) says, among other
> things
> 
>        EAGAIN Too many processes are already running.
> 
>        ENOMEM Cannot allocate sufficient memory to allocate a task
>               structure for the child, or to copy those parts of the
>               caller's context that need to be copied.
> 
> I have difficulties to read "lack of other resources" into the case
> for thrd_nomem. I see that EAGAIN is relatively well covered by
> thrd_error, but not very well by thrd_nomem. thrd_nomem is the
> catch-all-the-rest error, so I think that C11 permits to map EAGAIN
> together with eventually happening other exotic stuff on on it.

It should be noted that mmap/mprotect, as used by pthread_create, can
experience ENOMEM without memory exhaustion, as a result of a separate
limit: the kernel's limit on the number of VMAs a process can have. By
default I think this is something like 64k, and each thread with a
guard page uses two. I don't see how hitting the VMA limit is
significantly different than hidding the kernel task ("process")
limit. The reason I bring this up is because the VMA limit is
indistinguishable, at the syscall level, from memory exhaustion --
both cases give ENOMEM.

In both cases -- EAGAIN for pthread_create and thrd_nomem for
thrd_create, the error tells the application something useful: that
the failure is potentially transient. Whether it's actually transient
depends a lot on the application; if the app has a lot of memory tied
up that won't be freed asynchronously, then it's unlikely to be
transient, but if the app has threads responding to asynchronous
events (like requests from the network) it's very possible that the
needed resource will be available as soon as some of them complete.

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.