This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [RFC v2 08/20] sysdeps/wait: Use waitid if avaliable
* Arnd Bergmann:
> On Wed, Jun 26, 2019 at 5:48 PM Florian Weimer <fweimer@redhat.com> wrote:
>>
>> * Arnd Bergmann:
>>
>> [Exposing futex as __NR_futex for 64-bit-only-time_t]
>
>
> I'm realizing now that I was missing your point as I took futex as
> an example assuming we would handle all 21 time64 syscalls the
> same way, but you point out some issues that are specific to futex,
> so I should try to separate those two things.
>
>> > Is there any long-term advantage for your approach that I'm
>> > missing?
>>
>> Userspace that calls futex and does not care about timeouts would just
>> work on RV32 without any porting.
>
> In general, my hope is that anything should just work on rv32 without
> porting, regardless of the timeouts.
>
> One problem specific to futex is the fact that glibc does not come with
> a wrapper for it, so it's up to the applications to decide on which macro
> to pass.
That's hardly special to futex. Even if there's a perfectly fine
wrapper, some people don't want to use it.
> For most of the other syscalls, having rv32 not define the macro means
> that we break applications at compile-time, and are hopefully able to
> fix them in a way that works on all architectures. In case of futex,
> I agree that it would be better not to break compilation when you
> don't pass a timeout, but I see no good way to have it both ways.
I'm more and more confused here.
Does rv32 still have 32-bit struct timeval/struct timespec outside
getrusage?
If not, there is no risk at all that programmers confuse the types, and
no need to rename the systen calls.
If there's only a 64-bit time_t, calling futex futex_time64 makes as
much sense as alpha calling getpid getxpid.
> I hope the example of g_futex_wait() becomes a little easier after
> we have come up with a solution for fixing the much harder case
> of using __NR_futex /with/ timeouts, such as (also from glib)
>
> gboolean
> g_cond_wait_until (GCond *cond, GMutex *mutex, gint64 end_time)
> {
> struct timespec span;
> ...
> res = syscall (__NR_futex, &cond->i[0], (gsize) FUTEX_WAIT_PRIVATE,
> (gsize) sampled, &span);
> ...
> }
>
> The problem obviously is that on existing 32-bit architectures,
> the first argument (__NR_futex) must correspond to the type
> of the 'span' variable. Fixing this is always ugly, but has to be
> done. The best I can think of is
>
> gboolean
> g_cond_wait_until (GCond *cond, GMutex *mutex, gint64 end_time)
> {
> struct timespec span;
> ...
> res = -ENOSYS;
> if (sizeof(time_t) > sizeof(__syscall_slong_t)) {
> #ifdef __NR_futex_time64
> res = syscall (__NR_futex_time64, &cond->i[0], (gsize) FUTEX_WAIT_PRIVATE,
> (gsize) sampled, &span);
> #endif
> } else {
> #ifdef __NR_futex
> res = syscall (__NR_futex, &cond->i[0], (gsize) FUTEX_WAIT_PRIVATE,
> (gsize) sampled, &span);
> #endif
> }
> ...
> }
> The version above will
> - always use __NR_futex on 64-bit architectures and x32
> - use __NR_futex on 32-bit architectures with 32-bit time_t, this will always
> work except on kernels that don't support time32 syscalls (as intended)
> - use __NR_futex_time64 on 32-bit architectures with 64-bit time_t, which
> works when built with linux-5.1+ headers and running on linux-5.1+.
> This is probably good enough, as many other things are also broken
> when trying to use time64 with older kernels or headers.
I think the quoted fix isn't the best we can do. Portable binaries
32-bit binaries need to call futex_time64 once to see if it is
available, and fall back to futex if it is not. g_cond_wait_until in
particular does not have a dependency on the size of struct timespec,
but other parts of glib might, and it may not be possible to compile
glib as a while with __TIMESIZE == 64.
But t his is really an aside. I'm concerned that porting software to
rv32 requires that applications have to deal with the time_t transition
today, and I don't see a good reason for linking the two.
Thanks,
Florian