[RFC 03/10] y2038: Convert __lll_futex* functions to use futex_time64 when available

Lukasz Majewski lukma@denx.de
Sun Jul 12 13:43:10 GMT 2020


Dear Community,

> As the 'futex' syscall is wrapped with a C preprocessor macros, it was
> necessary to provide new set of those to replace call it with Y2038
> safe 'futex_time64' syscall.
> 
> The current code expand wrapper's arguments as __VA_ARGS__ when more
> than three arguments are passed. For the conversion it was necessary
> to also have 'timeout' explicitly passed, and hence the introduction
> of lll_futex_syscall_time64_4 and lll_futex_syscall_time64 functions.
> The former expects exactly 4 arguments - timeout is the last one.
> 

Comments are more than welcome.

> Signed-off-by: Lukasz Majewski <lukma@denx.de>
> ---
>  sysdeps/nptl/lowlevellock-futex.h | 80
> ++++++++++++++++++++++++++++--- sysdeps/nptl/lowlevellock.h       |
> 2 +- 2 files changed, 75 insertions(+), 7 deletions(-)
> 
> diff --git a/sysdeps/nptl/lowlevellock-futex.h
> b/sysdeps/nptl/lowlevellock-futex.h index 2209ca76a1..a686773db4
> 100644 --- a/sysdeps/nptl/lowlevellock-futex.h
> +++ b/sysdeps/nptl/lowlevellock-futex.h
> @@ -65,14 +65,82 @@
>    (((fl) | FUTEX_PRIVATE_FLAG) ^ (private))
>  # endif
>  
> -# define lll_futex_syscall(nargs, futexp, op, ...)
>    \ +# define __lll_futex_syscall(nargs, futexp, op, ...)
> 	        \ ({
>                   \
> -    long int __ret = INTERNAL_SYSCALL (futex, nargs, futexp, op,
> 	\
> +    long int __ret = INTERNAL_SYSCALL (futex, nargs, futexp, op,
>    \ __VA_ARGS__);                    \
>      (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (__ret))
> 	\ ? -INTERNAL_SYSCALL_ERRNO (__ret) : 0);
> 	\ })
>  
> +# define __lll_futex_syscall64(nargs, futexp, op, ...)	\
> +  ({
>    \
> +    long int __ret = INTERNAL_SYSCALL (futex_time64, nargs, futexp,
> op,	\
> +				       __VA_ARGS__);
> 	\
> +    (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (__ret))
> 	\
> +     ? -INTERNAL_SYSCALL_ERRNO (__ret) : 0);
> 	\
> +  })
> +
> +# ifdef __ASSUME_TIME64_SYSCALLS
> +#  ifndef __NR_futex_time64
> +#   define __NR_futex_time64 __NR_futex
> +#  endif
> +#  define lll_futex_syscall(nargs, futexp, op, ...)
> 	\
> +  __lll_futex_syscall64(nargs, futexp, op, __VA_ARGS__)
> +#  define lll_futex_syscall_time64_4(nargs, futexp, op, val,
> timeout)\
> +  __lll_futex_syscall64(nargs, futexp, op, val, timeout)
> +#  define lll_futex_syscall_time64(nargs, futexp, op, val, timeout,
> ...)\
> +  __lll_futex_syscall64(nargs, futexp, op, val, timeout, __VA_ARGS__)
> +# else
> +inline static long int
> +__lll_futex_syscall_time_check (long int __ret, const struct
> __timespec64 *t) +{
> +  if (! (__ret == 0 || errno != ENOSYS))
> +      if (t != NULL && ! in_time_t_range (t->tv_sec))
> +	__ret = ({ errno = (EOVERFLOW); -1l; });
> +  return __ret;
> +}
> +#  define lll_futex_syscall(nargs, futexp, op, ...)
> 	\
> +  ({
>    \
> +    long int __ret =
>    \
> +    __lll_futex_syscall64(nargs, futexp, op, __VA_ARGS__);	\
> +    if (! (__ret == 0 || errno != ENOSYS))
>    \
> +      __ret =
>    \
> +        __lll_futex_syscall(nargs, futexp, op, __VA_ARGS__);     \
> +    __ret;
>    \
> +  })
> +
> +#  define lll_futex_syscall_time64(nargs, futexp, op, val, timeout,
> ...)\
> +  ({
>    \
> +    struct timespec __ts32;
> 	\
> +    if (timeout != NULL)
>    \
> +      __ts32 = valid_timespec64_to_timespec (*((struct
> __timespec64*) timeout)); \
> +    long int __ret =
>    \
> +      __lll_futex_syscall64(nargs, futexp, op, val, timeout,\
> +			  __VA_ARGS__);
> 		\
> +    __ret = __lll_futex_syscall_time_check (__ret, timeout);
>    \
> +    if (__ret != 0)
>    \
> +      __ret = __lll_futex_syscall(nargs, futexp, op, val,        \
> +				  timeout != NULL ? &__ts32 : NULL,
>    \
> +				  __VA_ARGS__);
> 		\
> +    __ret;
>    \
> +  })
> +
> +#  define lll_futex_syscall_time64_4(nargs, futexp, op, val,
> timeout)\
> +  ({
>    \
> +    struct timespec __ts32;
> 	\
> +    if (timeout != NULL)
>    \
> +      __ts32 = valid_timespec64_to_timespec (*((struct
> __timespec64*) timeout)); \
> +    long int __ret =
>    \
> +      __lll_futex_syscall64(nargs, futexp, op, val, timeout);
> 	\
> +    __ret = __lll_futex_syscall_time_check (__ret, timeout);
>    \
> +    if (__ret != 0)
>    \
> +      __ret = __lll_futex_syscall(nargs, futexp, op, val,
>    \
> +				  timeout != NULL ? &__ts32 :
> NULL);	\
> +    __ret;
>    \
> +  })
> +
> +# endif
>  /* For most of these macros, the return value is never really used.
>     Nevertheless, the protocol is that each one returns a negated
> errno code for failure or zero for success.  (Note that the
> corresponding @@ -85,7 +153,7 @@
>    lll_futex_timed_wait (futexp, val, NULL, private)
>  
>  # define lll_futex_timed_wait(futexp, val, timeout, private)     \
> -  lll_futex_syscall (4, futexp,                                 \
> +  lll_futex_syscall_time64_4 (4, futexp,
>     \ __lll_private_flag (FUTEX_WAIT, private),  \
>  		     val, timeout)
>  
> @@ -107,7 +175,7 @@
>          const int op =
>    \ __lll_private_flag (FUTEX_WAIT_BITSET | clockbit, private);   \
>                                                                          \
> -        __ret = lll_futex_syscall (6, futexp, op, val,
>    \
> +        __ret = lll_futex_syscall_time64 (6, futexp, op, val,
>    \ timeout, NULL /* Unused.  */,	\
>                                     FUTEX_BITSET_MATCH_ANY);
> 	\ }
>       \ @@ -118,7 +186,7 @@
>  
>  /* Wake up up to NR waiters on FUTEXP.  */
>  # define lll_futex_wake(futexp, nr, private)
>     \
> -  lll_futex_syscall (4, futexp,
>    \
> +  lll_futex_syscall_time64_4 (4, futexp,
>     \ __lll_private_flag (FUTEX_WAKE, private), nr, 0)
>  
>  /* Wake up up to NR_WAKE waiters on FUTEXP.  Move up to NR_MOVE of
> the @@ -159,7 +227,7 @@
>  /* Like lll_futex_wait_requeue_pi, but with a timeout.  */
>  # define lll_futex_timed_wait_requeue_pi(futexp, val, timeout,
> clockbit, \ mutex, private)                 \
> -  lll_futex_syscall (5, futexp,
>    \
> +  lll_futex_syscall_time64 (5, futexp,
>    \ __lll_private_flag (FUTEX_WAIT_REQUEUE_PI          \
>  					 | (clockbit), private),
>    \ val, timeout, mutex)
> diff --git a/sysdeps/nptl/lowlevellock.h b/sysdeps/nptl/lowlevellock.h
> index 68b3be8819..864152e609 100644
> --- a/sysdeps/nptl/lowlevellock.h
> +++ b/sysdeps/nptl/lowlevellock.h
> @@ -123,7 +123,7 @@ extern void __lll_lock_wait (int *futex, int
> private) attribute_hidden; 
>  
>  extern int __lll_clocklock_wait (int *futex, int val, clockid_t,
> -				 const struct timespec *,
> +				 const struct __timespec64 *,
>  				 int private) attribute_hidden;
>  
>  #define lll_timedwait(futex, val, clockid, abstime, private)
> 	\




Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-59 Fax: (+49)-8142-66989-80 Email: lukma@denx.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <https://sourceware.org/pipermail/libc-alpha/attachments/20200712/0e48280c/attachment.sig>


More information about the Libc-alpha mailing list