#if __TIMESIZE == 64
# define __pthread_clockjoin_np64 __pthread_clockjoin_np
# define __pthread_timedjoin_np64 __pthread_timedjoin_np
+# define __pthread_cond_timedwait64 __pthread_cond_timedwait
+# define __pthread_cond_clockwait64 __pthread_cond_clockwait
#else
extern int __pthread_clockjoin_np64 (pthread_t threadid, void **thread_return,
clockid_t clockid,
extern int __pthread_timedjoin_np64 (pthread_t threadid, void **thread_return,
const struct __timespec64 *abstime);
libc_hidden_proto (__pthread_timedjoin_np64)
+extern int __pthread_cond_timedwait64 (pthread_cond_t *cond,
+ pthread_mutex_t *mutex,
+ const struct __timespec64 *abstime);
+libpthread_hidden_proto (__pthread_cond_timedwait64)
+extern int __pthread_cond_clockwait64 (pthread_cond_t *cond,
+ pthread_mutex_t *mutex,
+ clockid_t clockid,
+ const struct __timespec64 *abstime);
+libpthread_hidden_proto (__pthread_cond_clockwait64)
#endif
extern int __pthread_cond_timedwait (pthread_cond_t *cond,
*/
static __always_inline int
__pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
- clockid_t clockid,
- const struct timespec *abstime)
+ clockid_t clockid, const struct __timespec64 *abstime)
{
const int maxspin = 0;
int err;
err = ETIMEDOUT;
else
{
- err = futex_abstimed_wait_cancelable
+ err = __futex_abstimed_wait_cancelable64
(cond->__data.__g_signals + g, 0, clockid, abstime,
private);
}
/* See __pthread_cond_wait_common. */
int
-__pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
- const struct timespec *abstime)
+__pthread_cond_timedwait64 (pthread_cond_t *cond, pthread_mutex_t *mutex,
+ const struct __timespec64 *abstime)
{
/* Check parameter validity. This should also tell the compiler that
it can assume that abstime is not NULL. */
? CLOCK_MONOTONIC : CLOCK_REALTIME;
return __pthread_cond_wait_common (cond, mutex, clockid, abstime);
}
+
+#if __TIMESIZE != 64
+libpthread_hidden_def (__pthread_cond_timedwait64)
+
+int
+__pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
+ const struct timespec *abstime)
+{
+ struct __timespec64 ts64 = valid_timespec_to_timespec64 (*abstime);
+
+ return __pthread_cond_timedwait64 (cond, mutex, &ts64);
+}
+#endif
+
versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
GLIBC_2_3_2);
versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
/* See __pthread_cond_wait_common. */
int
-__pthread_cond_clockwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
- clockid_t clockid,
- const struct timespec *abstime)
+__pthread_cond_clockwait64 (pthread_cond_t *cond, pthread_mutex_t *mutex,
+ clockid_t clockid,
+ const struct __timespec64 *abstime)
{
/* Check parameter validity. This should also tell the compiler that
it can assume that abstime is not NULL. */
return __pthread_cond_wait_common (cond, mutex, clockid, abstime);
}
+
+#if __TIMESIZE != 64
+libpthread_hidden_def (__pthread_cond_clockwait64)
+
+int
+__pthread_cond_clockwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
+ clockid_t clockid,
+ const struct timespec *abstime)
+{
+ struct __timespec64 ts64 = valid_timespec_to_timespec64 (*abstime);
+
+ return __pthread_cond_clockwait64 (cond, mutex, clockid, &ts64);
+}
+#endif
weak_alias (__pthread_cond_clockwait, pthread_cond_clockwait);
# <https://www.gnu.org/licenses/>.
ifeq ($(subdir),nptl)
-libpthread-sysdep_routines += errno-loc
+libpthread-sysdep_routines += errno-loc futex-internal
endif
ifeq ($(subdir),rt)
--- /dev/null
+/* futex helper functions for glibc-internal use.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <sysdep.h>
+#include <time.h>
+#include <futex-internal.h>
+#include <kernel-features.h>
+
+#ifndef __ASSUME_TIME64_SYSCALLS
+static int
+__futex_abstimed_wait_cancellable32 (unsigned int* futex_word,
+ unsigned int expected, clockid_t clockid,
+ const struct __timespec64* abstime,
+ int private)
+{
+ if (! in_time_t_range (abstime->tv_sec))
+ return -EOVERFLOW;
+
+ unsigned int clockbit = (clockid == CLOCK_REALTIME)
+ ? FUTEX_CLOCK_REALTIME : 0;
+ int op = __lll_private_flag (FUTEX_WAIT_BITSET | clockbit, private);
+
+ struct timespec ts32 = valid_timespec64_to_timespec (*abstime);
+ return INTERNAL_SYSCALL_CANCEL (futex, futex_word, op, expected,
+ &ts32, NULL /* Unused. */,
+ FUTEX_BITSET_MATCH_ANY);
+}
+#endif
+
+int
+__futex_abstimed_wait_cancelable64 (unsigned int* futex_word,
+ unsigned int expected, clockid_t clockid,
+ const struct __timespec64* abstime,
+ int private)
+{
+ unsigned int clockbit;
+ int err;
+
+ /* Work around the fact that the kernel rejects negative timeout values
+ despite them being valid. */
+ if (__glibc_unlikely ((abstime != NULL) && (abstime->tv_sec < 0)))
+ return ETIMEDOUT;
+
+ if (! lll_futex_supported_clockid (clockid))
+ return EINVAL;
+
+ clockbit = (clockid == CLOCK_REALTIME) ? FUTEX_CLOCK_REALTIME : 0;
+ int op = __lll_private_flag (FUTEX_WAIT_BITSET | clockbit, private);
+
+ err = INTERNAL_SYSCALL_CANCEL (futex_time64, futex_word, op, expected,
+ abstime, NULL /* Unused. */,
+ FUTEX_BITSET_MATCH_ANY);
+#ifndef __ASSUME_TIME64_SYSCALLS
+if (err == -ENOSYS)
+ err = __futex_abstimed_wait_cancellable32 (futex_word, expected,
+ clockid, abstime, private);
+#endif
+
+ switch (err)
+ {
+ case 0:
+ case -EAGAIN:
+ case -EINTR:
+ case -ETIMEDOUT:
+ case -EOVERFLOW: /* Passed absolute timeout uses 64 bit time_t type, but
+ underlying kernel does not support 64 bit time_t futex
+ syscalls. */
+ return -err;
+
+ case -EFAULT: /* Must have been caused by a glibc or application bug. */
+ case -EINVAL: /* Either due to wrong alignment or due to the timeout not
+ being normalized. Must have been caused by a glibc or
+ application bug. */
+ case -ENOSYS: /* Must have been caused by a glibc bug. */
+ /* No other errors are documented at this time. */
+ default:
+ futex_fatal_error ();
+ }
+}
futex_fatal_error ();
}
}
+
+/* The futex_abstimed_wait_cancelable64 has been moved to a separate file
+ to avoid problems with exhausting available registers on some architectures
+ - e.g. on m68k architecture. */
+int
+__futex_abstimed_wait_cancelable64 (unsigned int* futex_word,
+ unsigned int expected, clockid_t clockid,
+ const struct __timespec64* abstime,
+ int private) attribute_hidden;
+
#endif /* futex-internal.h */