This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Principles for syscall wrappers, again


On Fri, 2015-05-29 at 13:21 +0000, Joseph Myers wrote:
> On Fri, 29 May 2015, Torvald Riegel wrote:
> 
> > On Fri, 2015-05-29 at 11:19 +0000, Joseph Myers wrote:
> > > I think it would have been harmful to users to insist that all unknown 
> > > ioctl uses go through the syscall function unless we've individually 
> > > reviewed and second-guessed the interface in every case - it would just 
> > > gratuitously complicate their code.  And I think the same applies to 
> > > futex.
> > 
> > That may be a proper analogy if we'd be looking at adding a futex API
> > while the kernel-level set of futex operations still evolved.  But right
> > now, we're looking at a pretty stable set of operations, and we have
> > documentation from the kernel that actually describes the intended
> > logical API (which is then transformed into the multiplexing scheme
> > used).
> > 
> > Thus, if people start with the futex docs to understand how the futex
> > operations work -- and they should do that --, then what complicates a
> > futex interface would be the multiplexing interface itself (e.g., the
> > wild parameter reuse), not the alternative interface I outlined.
> 
> I'd expect people to look at "man futex" on their distribution, and to 
> expect a C function with the interface described there.  I looked at the 
> branch you referenced 
> <http://git.kernel.org/cgit/docs/man-pages/man-pages.git/tree/man2/futex.2?h=draft_futex> 
> and I still don't see descriptions of the different C interfaces you 
> describe.

Well, the C interface they show is the multiplexing one -- that's why I
spoke about the "logical", intended API.  Look into the actual
descriptions of the individual operations.  Those do read like separate
functions to, and that would also what would make sense.  For example
futex_wait:
   This operation tests that the value at the futex word pointed to
   by  the address uaddr still contains the expected value val, and
   if so, then sleeps awaiting FUTEX_WAKE on the futex  word. [...]

Don't you think it is easier to remember how to use it if we have this?:
  int futex_wait(int* futex_word, int flags, int expected_value,
    const struct timespec *timeout);

Note that the rest of the manpage uses "futex word" consistently to name
the int variable that holds the userspace state for the futex, for
example.

> > Also, it's not like it should take us long to decide on a proper futex
> > interface, nor would that matter much given that we haven't had any
> > futex interface for a long time.  Or are you thinking about other kinds
> > of complications?
> > 
> > And I still don't really see the harm for users.  Can you be more
> > specific?  Are you concerned about availability, or timely availability,
> > or deviation to the lowest-level OS interface, or usability, or ...?
> 
> All of these.

Really?  Usability includes ease-of-use to me, and having to put an int
into a timespec* parameter that has a completely unintuitive name for
that use really does conflict with ease-of-use to me.  Why do you think
that's not the case?

> I think glibc will be more useful in practice if we are 
> more willing to delegate certain areas of low-level API design and 
> implement APIs designed in the Linux kernel community like we do with 
> POSIX APIs.

I doubt the POSIX API and the Linux syscall APIs have the same target
users.  If we had a futex API that would be at a level similar to POSIX,
that may be fine.  And I also agree that we might want to expose the
lowest-level API we can do (ie, futex() if we ignore syscall()) -- but
that doesn't mean that the lowest-level API is what would actually be
useful to users.

futexes are most useful for people that want to implement their own
blocking synchronization, and for that to be useful in the GNU system
(which you seem to be concerned about), we need to have an API that
makes sense in this context and is well-integrated with how we do
atomics on the GNU system.  That's why I have proposed patches for the
futex kernel docs that clarify what is atomic wrt. what etc.

> I think this discussion has illustrated my point: discussions 
> here of the detailed design of such APIs get into ratholes

Please note that we're not even discussing here how a proper futex API
should look, so we don't even know if we'd disagree about it.  Thus, I
disagree with your claim that we're in *that* rathole.

> consuming 
> limited resources (look at the size of the patch review backlog in 
> patchwork), and so we should have principles that as far as possible 
> delegate the design to external communities and respect their choices, 
> reducing the set of choices needing review here.  Only in the cases where 
> there isn't a suitable external API do we then need to do the detailed 
> design ourselves.

I'm confused.  You said you don't see adding futex() as a reason to not
add a proper futex interface, yet here you seem to say that the latter
would be bad for us.  Can you clarify?

> > > The fact that, with hindsight, we might not have designed an API 
> > > the way it was in fact designed does not mean we should embed that 
> > > viewpoint in the choice of APIs provided to users.
> > 
> > If we have the hindsight, why should we ignore it?  It's not even just
> > our hindsight in this case, we're following the kernel docs mostly.
> 
> Because whatever the issues with the kernel API, at least it's an API 
> people know and can see in their futex manpages.

But that manpage doesn't discuss cancellation, or does it?  So it's not
complete anyway from our POV.

I have worked on that futex manpage draft; based on that experience, I
bet that the manpage would be easier to consume and the interface easier
to use if we wouldn't multiplex in the interface.

Also, the futex API is, I'd argue, a collaborative kernel/glibc API.
For quite a while, the most useful docs on it where a combination of
Ulrich's paper and the futex syscall manpage.  Some of the error
conditions (e.g., spurious wake-ups) are a direct result of how glibc is
using futexes (and how similar synchronization code in other libraries
would do).

> If you wish to define a more precise rule for determining the kernel's 
> intended API - for determining the set of userspace C functions intended 
> to correspond to a C syscall - that's fine, as long as it's generally 
> clear how to apply that rule.  What I don't want is detailed redesign of 
> APIs in the absence of strong evidence of kernel intent.

As I said, I'm speaking about futexes specifically here, and claim that
a different API than the multiplexing one is significantly easier and
less error-prone to use.  I'm also claiming that a different API would
be easier to follow even with just the current Linux manpage.

In the general case, I just want us to (1) consider whether, for a
particular syscall, we are in a similar situation as for futexes; (2)
discuss the situation and see whether there is consensus on offering an
API that is more useful to the majority of glibc users or GNU system
developers; and (3) try to provide such an API in the same release in
which we might provide a lowest-level API as well.

(I'm adding (3) because I don't want us to provide futex() suport in
release N, followed by users creating their own wrappers for it if they
want cleaner interfaces -- and then we provide a proper interface in
release N+1 and everyone has to change again or live with their own
variants.)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]