diff options
author | Lukasz Majewski <lukma@denx.de> | 2020-09-18 20:54:13 +0200 |
---|---|---|
committer | Lukasz Majewski <lukma@denx.de> | 2020-10-15 09:35:43 +0200 |
commit | 29e9874a048f47e2d46c40253036c8d2de921548 (patch) | |
tree | 89bf596e3db06ad009bca5ba0b5ee947732d8f68 /nptl | |
parent | 9ebaabeaac1a96b0d91f52902ce1dbf4f5a562dd (diff) | |
download | glibc-29e9874a048f47e2d46c40253036c8d2de921548.tar glibc-29e9874a048f47e2d46c40253036c8d2de921548.tar.gz glibc-29e9874a048f47e2d46c40253036c8d2de921548.tar.bz2 glibc-29e9874a048f47e2d46c40253036c8d2de921548.zip |
y2038: nptl: Convert pthread_mutex_{clock|timed}lock to support 64 bit
The pthread_mutex_clocklock and pthread_mutex_timedlock have been converted
to support 64 bit time.
This change uses:
- New __futex_clocklock_wait64 (instead of lll_timedwait)
from ./sysdeps/nptl/futex-helpers.c and
- New __futex_clocklock64 function (instead of lll_clocklock)
- New futex_lock_pi64
defined in sysdeps/nptl/futex-internal.h
The pthread_mutex_{clock|timed}lock only accepts absolute time.
Moreover, there is no need to check for NULL passed as *abstime pointer to the
syscalls as those calls have exported symbols marked with __nonull attribute
for abstime.
Some architectures - namely x86, powerpc and s390 - do support lock elision.
For those - adjustments have been made in arch specific elision-*.c files
to use __futex_clocklock64 instead of lll_clocklock.
The __lll_lock_elision (aliased to __lll_clocklock_elision in e.g.
sysdeps/unix/sysv/linux/s390/elision-timed.c) just uses, in this patch
provided, __futex_clocklock64.
For systems with __TIMESIZE != 64 && __WORDSIZE == 32:
- Conversions between 64 bit time to 32 bit are necessary
- Redirection to pthread_mutex_{clock|timed}lock will provide support for 64
bit time
Build tests:
./src/scripts/build-many-glibcs.py glibcs
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Diffstat (limited to 'nptl')
-rw-r--r-- | nptl/pthreadP.h | 9 | ||||
-rw-r--r-- | nptl/pthread_mutex_timedlock.c | 66 |
2 files changed, 55 insertions, 20 deletions
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h index 5bcc8a2db5..710b21e890 100644 --- a/nptl/pthreadP.h +++ b/nptl/pthreadP.h @@ -468,6 +468,8 @@ extern int __pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex); # define __pthread_rwlock_clockwrlock64 __pthread_rwlock_clockwrlock # define __pthread_rwlock_timedrdlock64 __pthread_rwlock_timedrdlock # define __pthread_rwlock_timedwrlock64 __pthread_rwlock_timedwrlock +# define __pthread_mutex_clocklock64 __pthread_mutex_clocklock +# define __pthread_mutex_timedlock64 __pthread_mutex_timedlock #else extern int __pthread_clockjoin_np64 (pthread_t threadid, void **thread_return, clockid_t clockid, @@ -499,6 +501,13 @@ libpthread_hidden_proto (__pthread_rwlock_timedrdlock64) extern int __pthread_rwlock_timedwrlock64 (pthread_rwlock_t *rwlock, const struct __timespec64 *abstime); libpthread_hidden_proto (__pthread_rwlock_timedwrlock64) +extern int __pthread_mutex_clocklock64 (pthread_mutex_t *mutex, + clockid_t clockid, + const struct __timespec64 *abstime); +libpthread_hidden_proto (__pthread_mutex_clocklock64) +extern int __pthread_mutex_timedlock64 (pthread_mutex_t *mutex, + const struct __timespec64 *abstime); +libpthread_hidden_proto (__pthread_mutex_timedlock64) #endif extern int __pthread_cond_timedwait (pthread_cond_t *cond, diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c index 8ae814b984..dc40399f02 100644 --- a/nptl/pthread_mutex_timedlock.c +++ b/nptl/pthread_mutex_timedlock.c @@ -31,7 +31,7 @@ #ifndef lll_clocklock_elision #define lll_clocklock_elision(futex, adapt_count, clockid, abstime, private) \ - lll_clocklock (futex, clockid, abstime, private) + __futex_clocklock64 (&(futex), clockid, abstime, private) #endif #ifndef lll_trylock_elision @@ -45,7 +45,7 @@ int __pthread_mutex_clocklock_common (pthread_mutex_t *mutex, clockid_t clockid, - const struct timespec *abstime) + const struct __timespec64 *abstime) { int oldval; pid_t id = THREAD_GETMEM (THREAD_SELF, tid); @@ -76,8 +76,8 @@ __pthread_mutex_clocklock_common (pthread_mutex_t *mutex, } /* We have to get the mutex. */ - result = lll_clocklock (mutex->__data.__lock, clockid, abstime, - PTHREAD_MUTEX_PSHARED (mutex)); + result = __futex_clocklock64 (&mutex->__data.__lock, clockid, abstime, + PTHREAD_MUTEX_PSHARED (mutex)); if (result != 0) goto out; @@ -99,8 +99,8 @@ __pthread_mutex_clocklock_common (pthread_mutex_t *mutex, FORCE_ELISION (mutex, goto elision); simple: /* Normal mutex. */ - result = lll_clocklock (mutex->__data.__lock, clockid, abstime, - PTHREAD_MUTEX_PSHARED (mutex)); + result = __futex_clocklock64 (&mutex->__data.__lock, clockid, abstime, + PTHREAD_MUTEX_PSHARED (mutex)); break; case PTHREAD_MUTEX_TIMED_ELISION_NP: @@ -125,9 +125,9 @@ __pthread_mutex_clocklock_common (pthread_mutex_t *mutex, { if (cnt++ >= max_cnt) { - result = lll_clocklock (mutex->__data.__lock, - clockid, abstime, - PTHREAD_MUTEX_PSHARED (mutex)); + result = __futex_clocklock64 (&mutex->__data.__lock, + clockid, abstime, + PTHREAD_MUTEX_PSHARED (mutex)); break; } atomic_spin_nop (); @@ -378,8 +378,7 @@ __pthread_mutex_clocklock_common (pthread_mutex_t *mutex, int private = (robust ? PTHREAD_ROBUST_MUTEX_PSHARED (mutex) : PTHREAD_MUTEX_PSHARED (mutex)); - int e = futex_lock_pi ((unsigned int *) &mutex->__data.__lock, - abstime, private); + int e = futex_lock_pi64 (&mutex->__data.__lock, abstime, private); if (e == ETIMEDOUT) return ETIMEDOUT; else if (e == ESRCH || e == EDEADLK) @@ -394,8 +393,8 @@ __pthread_mutex_clocklock_common (pthread_mutex_t *mutex, /* Delay the thread until the timeout is reached. Then return ETIMEDOUT. */ do - e = lll_timedwait (&(int){0}, 0, clockid, abstime, - private); + e = __futex_clocklock_wait64 (&(int){0}, 0, clockid, abstime, + private); while (e != ETIMEDOUT); return ETIMEDOUT; } @@ -543,10 +542,10 @@ __pthread_mutex_clocklock_common (pthread_mutex_t *mutex, goto failpp; } - struct timespec rt; + struct __timespec64 rt; /* Get the current time. */ - __clock_gettime (CLOCK_REALTIME, &rt); + __clock_gettime64 (CLOCK_REALTIME, &rt); /* Compute relative timeout. */ rt.tv_sec = abstime->tv_sec - rt.tv_sec; @@ -599,9 +598,9 @@ __pthread_mutex_clocklock_common (pthread_mutex_t *mutex, } int -__pthread_mutex_clocklock (pthread_mutex_t *mutex, - clockid_t clockid, - const struct timespec *abstime) +__pthread_mutex_clocklock64 (pthread_mutex_t *mutex, + clockid_t clockid, + const struct __timespec64 *abstime) { if (__glibc_unlikely (!lll_futex_supported_clockid (clockid))) return EINVAL; @@ -609,13 +608,40 @@ __pthread_mutex_clocklock (pthread_mutex_t *mutex, LIBC_PROBE (mutex_clocklock_entry, 3, mutex, clockid, abstime); return __pthread_mutex_clocklock_common (mutex, clockid, abstime); } -weak_alias (__pthread_mutex_clocklock, pthread_mutex_clocklock) + +#if __TIMESIZE != 64 +libpthread_hidden_def (__pthread_mutex_clocklock64) int -__pthread_mutex_timedlock (pthread_mutex_t *mutex, +__pthread_mutex_clocklock (pthread_mutex_t *mutex, + clockid_t clockid, const struct timespec *abstime) { + struct __timespec64 ts64 = valid_timespec_to_timespec64 (*abstime); + + return __pthread_mutex_clocklock64 (mutex, clockid, &ts64); +} +#endif +weak_alias (__pthread_mutex_clocklock, pthread_mutex_clocklock) + +int +__pthread_mutex_timedlock64 (pthread_mutex_t *mutex, + const struct __timespec64 *abstime) +{ LIBC_PROBE (mutex_timedlock_entry, 2, mutex, abstime); return __pthread_mutex_clocklock_common (mutex, CLOCK_REALTIME, abstime); } + +#if __TIMESIZE != 64 +libpthread_hidden_def (__pthread_mutex_timedlock64) + +int +__pthread_mutex_timedlock (pthread_mutex_t *mutex, + const struct timespec *abstime) +{ + struct __timespec64 ts64 = valid_timespec_to_timespec64 (*abstime); + + return __pthread_mutex_timedlock64 (mutex, &ts64); +} +#endif weak_alias (__pthread_mutex_timedlock, pthread_mutex_timedlock) |