mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-08 14:20:07 +00:00
nptl: Add POSIX-proposed pthread_cond_clockwait
Add: int pthread_cond_clockwait (pthread_cond_t *cond, pthread_mutex_t *mutex, clockid_t clockid, const struct timespec *abstime) which behaves just like pthread_cond_timedwait except it always measures abstime against the supplied clockid. Currently supports CLOCK_REALTIME and CLOCK_MONOTONIC and returns EINVAL if any other clock is specified. Includes feedback from many others. This function was originally proposed[1] as pthread_cond_timedwaitonclock_np, but The Austin Group preferred the new name. * nptl/Makefile: Add tst-cond26 and tst-cond27 * nptl/Versions (GLIBC_2.30): Add pthread_cond_clockwait * sysdeps/nptl/pthread.h: Likewise * nptl/forward.c: Add __pthread_cond_clockwait * nptl/forward.c: Likewise * nptl/pthreadP.h: Likewise * sysdeps/nptl/pthread-functions.h: Likewise * nptl/pthread_cond_wait.c (__pthread_cond_wait_common): Add clockid parameter and comment describing why we don't need to check its value. Use that value when calling futex_abstimed_wait_cancelable rather than reading the clock from the flags. (__pthread_cond_wait): Pass unused clockid parameter. (__pthread_cond_timedwait): Read clock from flags and pass it to __pthread_cond_wait_common. (__pthread_cond_clockwait): Add new function with weak alias from pthread_cond_clockwait. * sysdeps/mach/hurd/i386/libpthread.abilist (GLIBC_2.30): * Likewise. * sysdeps/unix/sysv/linux/aarch64/libpthread.abilist * (GLIBC_2.30): Likewise. * sysdeps/unix/sysv/linux/alpha/libpthread.abilist (GLIBC_2.30): * Likewise. * sysdeps/unix/sysv/linux/arm/libpthread.abilist (GLIBC_2.30): * Likewise. * sysdeps/unix/sysv/linux/csky/libpthread.abilist (GLIBC_2.30): * Likewise. * sysdeps/unix/sysv/linux/hppa/libpthread.abilist (GLIBC_2.30): * Likewise. * sysdeps/unix/sysv/linux/i386/libpthread.abilist (GLIBC_2.30): * Likewise. * sysdeps/unix/sysv/linux/ia64/libpthread.abilist (GLIBC_2.30): * Likewise. * sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist (GLIBC_2.30): Likewise. * sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist (GLIBC_2.30): Likewise. * sysdeps/unix/sysv/linux/microblaze/libpthread.abilist (GLIBC_2.30): Likewise. * sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist (GLIBC_2.30): Likewise. * sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist (GLIBC_2.30): Likewise. * sysdeps/unix/sysv/linux/nios2/libpthread.abilist (GLIBC_2.30): * Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist (GLIBC_2.30): Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist (GLIBC_2.30): Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist (GLIBC_2.30): Likewise. * sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist (GLIBC_2.30): Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist (GLIBC_2.30): Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist (GLIBC_2.30): Likewise. * sysdeps/unix/sysv/linux/sh/libpthread.abilist (GLIBC_2.30): * Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist (GLIBC_2.30): Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist (GLIBC_2.30): Likewise. * sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist (GLIBC_2.30): Likewise. * sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist (GLIBC_2.30): Likewise. * nptl/tst-cond11.c (run_test): Support testing pthread_cond_clockwait too by using a special magic CLOCK_USE_ATTR_CLOCK value to determine whether to call pthread_cond_timedwait or pthread_cond_clockwait. (do_test): Pass CLOCK_USE_ATTR_CLOCK for existing tests, and add new tests using all combinations of CLOCK_MONOTONIC and CLOCK_REALTIME. * ntpl/tst-cond26.c: New test for passing unsupported and * invalid clocks to pthread_cond_clockwait. * nptl/tst-cond27.c: Add test similar to tst-cond5.c, but using struct timespec and pthread_cond_clockwait. * manual/threads.texi: Document pthread_cond_clockwait. The * comment was provided by Carlos O'Donell. [1] https://sourceware.org/ml/libc-alpha/2015-07/msg00193.html Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
This commit is contained in:
parent
6615f77978
commit
afe4de7d28
69
ChangeLog
69
ChangeLog
@ -1,5 +1,74 @@
|
||||
2019-07-12 Mike Crowe <mac@mcrowe.com>
|
||||
|
||||
nptl: Add POSIX-proposed pthread_cond_clockwait which behaves just
|
||||
like pthread_cond_timedwait except it always measures abstime
|
||||
against the supplied clockid.
|
||||
* nptl/Makefile: Add tst-cond26 and tst-cond27
|
||||
* nptl/Versions (GLIBC_2.30): Add pthread_cond_clockwait
|
||||
* sysdeps/nptl/pthread.h: Likewise
|
||||
* nptl/forward.c: Add __pthread_cond_clockwait
|
||||
* nptl/forward.c: Likewise
|
||||
* nptl/pthreadP.h: Likewise
|
||||
* sysdeps/nptl/pthread-functions.h: Likewise
|
||||
* nptl/pthread_cond_wait.c (__pthread_cond_wait_common): Add
|
||||
clockid parameter and comment describing why we don't need to check
|
||||
its value. Use that value when calling
|
||||
futex_abstimed_wait_cancelable rather than reading the clock from
|
||||
the flags. (__pthread_cond_wait): Pass unused clockid parameter.
|
||||
(__pthread_cond_timedwait): Read clock from flags and pass it to
|
||||
__pthread_cond_wait_common. (__pthread_cond_clockwait): Add new
|
||||
function with weak alias from pthread_cond_clockwait.
|
||||
* sysdeps/unix/sysv/linux/aarch64/libpthread.abilist (GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/alpha/libpthread.abilist (GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/arm/libpthread.abilist (GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/csky/libpthread.abilist (GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/hppa/libpthread.abilist (GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/i386/libpthread.abilist (GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/ia64/libpthread.abilist (GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/m68k/coldfire/libpthread.abilist
|
||||
(GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/m68k/m680x0/libpthread.abilist
|
||||
(GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/microblaze/libpthread.abilist
|
||||
(GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/mips/mips32/libpthread.abilist
|
||||
(GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/mips/mips64/libpthread.abilist
|
||||
(GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/nios2/libpthread.abilist (GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/powerpc/powerpc32/libpthread.abilist
|
||||
(GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libpthread.abilist
|
||||
(GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libpthread.abilist
|
||||
(GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/riscv/rv64/libpthread.abilist
|
||||
(GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/s390/s390-32/libpthread.abilist
|
||||
(GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/s390/s390-64/libpthread.abilist
|
||||
(GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/sh/libpthread.abilist (GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/sparc/sparc32/libpthread.abilist
|
||||
(GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/sparc/sparc64/libpthread.abilist
|
||||
(GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/x86_64/64/libpthread.abilist
|
||||
(GLIBC_2.30): Likewise.
|
||||
* sysdeps/unix/sysv/linux/x86_64/x32/libpthread.abilist
|
||||
(GLIBC_2.30): Likewise.
|
||||
* nptl/tst-cond11.c (run_test): Support testing
|
||||
pthread_cond_clockwait too by using a special magic
|
||||
CLOCK_USE_ATTR_CLOCK value to determine whether to call
|
||||
pthread_cond_timedwait or pthread_cond_clockwait. (do_test): Pass
|
||||
CLOCK_USE_ATTR_CLOCK for existing tests, and add new tests using
|
||||
all combinations of CLOCK_MONOTONIC and CLOCK_REALTIME.
|
||||
* ntpl/tst-cond26.c: New test for passing unsupported and invalid
|
||||
clocks to pthread_cond_clockwait.
|
||||
* nptl/tst-cond27.c: Add test similar to tst-cond5.c, but using
|
||||
struct timespec and pthread_cond_clockwait.
|
||||
* manual/threads.texi: Document pthread_cond_clockwait.
|
||||
|
||||
nptl: Add POSIX-proposed sem_clockwait which behaves just like
|
||||
sem_timedwait, but measures abstime against the specified clock.
|
||||
* nptl/sem_waitcommon.c (do_futex_wait, __new_sem_wait_slow): Add
|
||||
|
@ -679,6 +679,26 @@ against the clock specified by @var{clockid} rather than
|
||||
@code{CLOCK_MONOTONIC} or @code{CLOCK_REALTIME}.
|
||||
@end deftypefun
|
||||
|
||||
@comment pthread.h
|
||||
@comment POSIX-proposed
|
||||
@deftypefun int pthread_cond_clockwait (pthread_cond_t *@var{cond}, pthread_mutex_t *@var{mutex},
|
||||
clockid_t @var{clockid}, const struct timespec *@var{abstime})
|
||||
@safety{@prelim{}@mtsafe{}@asunsafe{@asulock{}}@acunsafe{@aculock{}}}
|
||||
@c If exactly the same function with arguments is called from a signal
|
||||
@c handler that interrupts between the mutex unlock and sleep then it
|
||||
@c will unlock the mutex twice resulting in undefined behaviour. Keep
|
||||
@c in mind that the unlock and sleep are only atomic with respect to other
|
||||
@c threads (really a happens-after relationship for pthread_cond_broadcast
|
||||
@c and pthread_cond_signal).
|
||||
@c In the AC case we would cancel the thread and the mutex would remain
|
||||
@c locked and we can't recover from that.
|
||||
Behaves like @code{pthread_cond_timedwait} except the time @var{abstime} is
|
||||
measured against the clock specified by @var{clockid} rather than the clock
|
||||
specified or defaulted when @code{pthread_cond_init} was called. Currently,
|
||||
@var{clockid} must be either @code{CLOCK_MONOTONIC} or
|
||||
@code{CLOCK_REALTIME}.
|
||||
@end deftypefun
|
||||
|
||||
@c FIXME these are undocumented:
|
||||
@c pthread_atfork
|
||||
@c pthread_attr_destroy
|
||||
|
@ -251,6 +251,7 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
|
||||
tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
|
||||
tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
|
||||
tst-cond20 tst-cond21 tst-cond22 tst-cond23 tst-cond24 tst-cond25 \
|
||||
tst-cond26 tst-cond27 \
|
||||
tst-cond-except \
|
||||
tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \
|
||||
tst-robust6 tst-robust7 tst-robust8 tst-robust9 \
|
||||
|
@ -277,7 +277,7 @@ libpthread {
|
||||
}
|
||||
|
||||
GLIBC_2.30 {
|
||||
sem_clockwait;
|
||||
sem_clockwait; pthread_cond_clockwait;
|
||||
}
|
||||
|
||||
GLIBC_PRIVATE {
|
||||
|
@ -164,6 +164,11 @@ FORWARD (__pthread_cond_timedwait,
|
||||
const struct timespec *abstime), (cond, mutex, abstime), 0)
|
||||
versioned_symbol (libc, __pthread_cond_timedwait, pthread_cond_timedwait,
|
||||
GLIBC_2_3_2);
|
||||
FORWARD (__pthread_cond_clockwait,
|
||||
(pthread_cond_t *cond, pthread_mutex_t *mutex, clockid_t clockid,
|
||||
const struct timespec *abstime), (cond, mutex, clockid, abstime),
|
||||
0)
|
||||
weak_alias (__pthread_cond_clockwait, pthread_cond_clockwait);
|
||||
|
||||
|
||||
FORWARD (pthread_equal, (pthread_t thread1, pthread_t thread2),
|
||||
|
@ -95,6 +95,7 @@ static const struct pthread_functions pthread_functions =
|
||||
.ptr___pthread_cond_signal = __pthread_cond_signal,
|
||||
.ptr___pthread_cond_wait = __pthread_cond_wait,
|
||||
.ptr___pthread_cond_timedwait = __pthread_cond_timedwait,
|
||||
.ptr___pthread_cond_clockwait = __pthread_cond_clockwait,
|
||||
# if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_3_2)
|
||||
.ptr___pthread_cond_broadcast_2_0 = __pthread_cond_broadcast_2_0,
|
||||
.ptr___pthread_cond_destroy_2_0 = __pthread_cond_destroy_2_0,
|
||||
|
@ -449,6 +449,11 @@ extern int __pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex);
|
||||
extern int __pthread_cond_timedwait (pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex,
|
||||
const struct timespec *abstime);
|
||||
extern int __pthread_cond_clockwait (pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex,
|
||||
clockid_t clockid,
|
||||
const struct timespec *abstime)
|
||||
__nonnull ((1, 2, 4));
|
||||
extern int __pthread_condattr_destroy (pthread_condattr_t *attr);
|
||||
extern int __pthread_condattr_init (pthread_condattr_t *attr);
|
||||
extern int __pthread_key_create (pthread_key_t *key, void (*destr) (void *));
|
||||
|
@ -378,6 +378,7 @@ __condvar_cleanup_waiting (void *arg)
|
||||
*/
|
||||
static __always_inline int
|
||||
__pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
clockid_t clockid,
|
||||
const struct timespec *abstime)
|
||||
{
|
||||
const int maxspin = 0;
|
||||
@ -386,6 +387,11 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
|
||||
LIBC_PROBE (cond_wait, 2, cond, mutex);
|
||||
|
||||
/* clockid will already have been checked by
|
||||
__pthread_cond_clockwait or pthread_condattr_setclock, or we
|
||||
don't use it if abstime is NULL, so we don't need to check it
|
||||
here. */
|
||||
|
||||
/* Acquire a position (SEQ) in the waiter sequence (WSEQ). We use an
|
||||
atomic operation because signals and broadcasts may update the group
|
||||
switch without acquiring the mutex. We do not need release MO here
|
||||
@ -511,10 +517,6 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
err = ETIMEDOUT;
|
||||
else
|
||||
{
|
||||
const clockid_t clockid =
|
||||
((flags & __PTHREAD_COND_CLOCK_MONOTONIC_MASK) != 0) ?
|
||||
CLOCK_MONOTONIC : CLOCK_REALTIME;
|
||||
|
||||
err = futex_abstimed_wait_cancelable
|
||||
(cond->__data.__g_signals + g, 0, clockid, abstime,
|
||||
private);
|
||||
@ -632,7 +634,8 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
int
|
||||
__pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
{
|
||||
return __pthread_cond_wait_common (cond, mutex, NULL);
|
||||
/* clockid is unused when abstime is NULL. */
|
||||
return __pthread_cond_wait_common (cond, mutex, 0, NULL);
|
||||
}
|
||||
|
||||
/* See __pthread_cond_wait_common. */
|
||||
@ -644,10 +647,39 @@ __pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
it can assume that abstime is not NULL. */
|
||||
if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
|
||||
return EINVAL;
|
||||
return __pthread_cond_wait_common (cond, mutex, abstime);
|
||||
|
||||
/* Relaxed MO is suffice because clock ID bit is only modified
|
||||
in condition creation. */
|
||||
unsigned int flags = atomic_load_relaxed (&cond->__data.__wrefs);
|
||||
clockid_t clockid = (flags & __PTHREAD_COND_CLOCK_MONOTONIC_MASK)
|
||||
? CLOCK_MONOTONIC : CLOCK_REALTIME;
|
||||
return __pthread_cond_wait_common (cond, mutex, clockid, abstime);
|
||||
}
|
||||
|
||||
/* See __pthread_cond_wait_common. */
|
||||
int
|
||||
__pthread_cond_clockwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
clockid_t clockid,
|
||||
const struct timespec *abstime)
|
||||
{
|
||||
/* Check parameter validity. This should also tell the compiler that
|
||||
it can assume that abstime is not NULL. */
|
||||
if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
|
||||
return EINVAL;
|
||||
|
||||
if (!futex_abstimed_supported_clockid (clockid))
|
||||
return EINVAL;
|
||||
|
||||
/* If we do not support waiting using CLOCK_MONOTONIC, return an error. */
|
||||
if (clockid == CLOCK_MONOTONIC
|
||||
&& !futex_supports_exact_relative_timeouts ())
|
||||
return EINVAL;
|
||||
|
||||
return __pthread_cond_wait_common (cond, mutex, clockid, abstime);
|
||||
}
|
||||
|
||||
versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
|
||||
GLIBC_2_3_2);
|
||||
versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
|
||||
GLIBC_2_3_2);
|
||||
weak_alias (__pthread_cond_clockwait, pthread_cond_clockwait);
|
||||
|
@ -22,28 +22,32 @@
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <support/check.h>
|
||||
#include <support/test-driver.h>
|
||||
#include <support/timespec.h>
|
||||
#include <support/xthread.h>
|
||||
#include <support/xtime.h>
|
||||
|
||||
/* A bogus clock value that tells run_test to use pthread_cond_timedwait
|
||||
rather than pthread_condclockwait. */
|
||||
#define CLOCK_USE_ATTR_CLOCK (-1)
|
||||
|
||||
#if defined _POSIX_CLOCK_SELECTION && _POSIX_CLOCK_SELECTION >= 0
|
||||
static int
|
||||
run_test (clockid_t cl)
|
||||
run_test (clockid_t attr_clock, clockid_t wait_clock)
|
||||
{
|
||||
pthread_condattr_t condattr;
|
||||
pthread_cond_t cond;
|
||||
pthread_mutexattr_t mutattr;
|
||||
pthread_mutex_t mut;
|
||||
|
||||
printf ("clock = %d\n", (int) cl);
|
||||
verbose_printf ("attr_clock = %d\n", (int) attr_clock);
|
||||
|
||||
TEST_COMPARE (pthread_condattr_init (&condattr), 0);
|
||||
TEST_COMPARE (pthread_condattr_setclock (&condattr, cl), 0);
|
||||
TEST_COMPARE (pthread_condattr_setclock (&condattr, attr_clock), 0);
|
||||
|
||||
clockid_t cl2;
|
||||
TEST_COMPARE (pthread_condattr_getclock (&condattr, &cl2), 0);
|
||||
TEST_COMPARE (cl, cl2);
|
||||
clockid_t attr_clock_read;
|
||||
TEST_COMPARE (pthread_condattr_getclock (&condattr, &attr_clock_read), 0);
|
||||
TEST_COMPARE (attr_clock, attr_clock_read);
|
||||
|
||||
TEST_COMPARE (pthread_cond_init (&cond, &condattr), 0);
|
||||
TEST_COMPARE (pthread_condattr_destroy (&condattr), 0);
|
||||
@ -57,13 +61,20 @@ run_test (clockid_t cl)
|
||||
TEST_COMPARE (pthread_mutex_lock (&mut), EDEADLK);
|
||||
|
||||
struct timespec ts_timeout;
|
||||
xclock_gettime (cl, &ts_timeout);
|
||||
xclock_gettime (wait_clock == CLOCK_USE_ATTR_CLOCK ? attr_clock : wait_clock,
|
||||
&ts_timeout);
|
||||
|
||||
/* Wait one second. */
|
||||
++ts_timeout.tv_sec;
|
||||
|
||||
TEST_COMPARE (pthread_cond_timedwait (&cond, &mut, &ts_timeout), ETIMEDOUT);
|
||||
TEST_TIMESPEC_BEFORE_NOW (ts_timeout, cl);
|
||||
if (wait_clock == CLOCK_USE_ATTR_CLOCK) {
|
||||
TEST_COMPARE (pthread_cond_timedwait (&cond, &mut, &ts_timeout), ETIMEDOUT);
|
||||
TEST_TIMESPEC_BEFORE_NOW (ts_timeout, attr_clock);
|
||||
} else {
|
||||
TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, wait_clock, &ts_timeout),
|
||||
ETIMEDOUT);
|
||||
TEST_TIMESPEC_BEFORE_NOW (ts_timeout, wait_clock);
|
||||
}
|
||||
|
||||
xpthread_mutex_unlock (&mut);
|
||||
xpthread_mutex_destroy (&mut);
|
||||
@ -83,7 +94,7 @@ do_test (void)
|
||||
|
||||
#else
|
||||
|
||||
run_test (CLOCK_REALTIME);
|
||||
run_test (CLOCK_REALTIME, CLOCK_USE_ATTR_CLOCK);
|
||||
|
||||
# if defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0
|
||||
# if _POSIX_MONOTONIC_CLOCK == 0
|
||||
@ -93,8 +104,13 @@ do_test (void)
|
||||
else if (e == 0)
|
||||
FAIL_RET ("sysconf (_SC_MONOTONIC_CLOCK) must not return 0");
|
||||
else
|
||||
{
|
||||
# endif
|
||||
run_test (CLOCK_MONOTONIC);
|
||||
run_test (CLOCK_MONOTONIC, CLOCK_USE_ATTR_CLOCK);
|
||||
run_test (CLOCK_REALTIME, CLOCK_MONOTONIC);
|
||||
run_test (CLOCK_MONOTONIC, CLOCK_MONOTONIC);
|
||||
run_test (CLOCK_MONOTONIC, CLOCK_REALTIME);
|
||||
}
|
||||
# else
|
||||
puts ("_POSIX_MONOTONIC_CLOCK not defined");
|
||||
# endif
|
||||
|
77
nptl/tst-cond26.c
Normal file
77
nptl/tst-cond26.c
Normal file
@ -0,0 +1,77 @@
|
||||
/* Test unsupported/bad clocks passed to pthread_cond_clockwait.
|
||||
|
||||
Copyright (C) 2019 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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <support/check.h>
|
||||
#include <support/timespec.h>
|
||||
#include <support/xthread.h>
|
||||
|
||||
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
|
||||
static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
#define NOT_A_VALID_CLOCK 123456
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
xpthread_mutex_lock (&mut);
|
||||
|
||||
const struct timespec ts = make_timespec (0, 0);
|
||||
|
||||
/* These clocks are meaningless to sem_clockwait. */
|
||||
#if defined(CLOCK_PROCESS_CPUTIME_ID)
|
||||
TEST_COMPARE (pthread_cond_clockwait (&cond, &mut,
|
||||
CLOCK_PROCESS_CPUTIME_ID, &ts), EINVAL);
|
||||
#endif
|
||||
#if defined(CLOCK_THREAD_CPUTIME_ID)
|
||||
TEST_COMPARE (pthread_cond_clockwait (&cond, &mut,
|
||||
CLOCK_THREAD_CPUTIME_ID, &ts), EINVAL);
|
||||
#endif
|
||||
|
||||
/* These clocks might be meaningful, but are currently unsupported
|
||||
by pthread_cond_clockwait. */
|
||||
#if defined(CLOCK_REALTIME_COARSE)
|
||||
TEST_COMPARE (pthread_cond_clockwait (&cond, &mut,
|
||||
CLOCK_REALTIME_COARSE, &ts), EINVAL);
|
||||
#endif
|
||||
#if defined(CLOCK_MONOTONIC_RAW)
|
||||
TEST_COMPARE (pthread_cond_clockwait (&cond, &mut,
|
||||
CLOCK_MONOTONIC_RAW, &ts), EINVAL);
|
||||
#endif
|
||||
#if defined(CLOCK_MONOTONIC_COARSE)
|
||||
TEST_COMPARE (pthread_cond_clockwait (&cond, &mut,
|
||||
CLOCK_MONOTONIC_COARSE, &ts), EINVAL);
|
||||
#endif
|
||||
#if defined(CLOCK_BOOTTIME)
|
||||
TEST_COMPARE (pthread_cond_clockwait (&cond, &mut,
|
||||
CLOCK_BOOTTIME, &ts), EINVAL);
|
||||
#endif
|
||||
|
||||
/* This is a completely invalid clock. */
|
||||
TEST_COMPARE (pthread_cond_clockwait (&cond, &mut,
|
||||
NOT_A_VALID_CLOCK, &ts), EINVAL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <support/test-driver.c>
|
66
nptl/tst-cond27.c
Normal file
66
nptl/tst-cond27.c
Normal file
@ -0,0 +1,66 @@
|
||||
/* Test pthread_cond_clockwait timeout.
|
||||
|
||||
Copyright (C) 2019 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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <support/check.h>
|
||||
#include <support/timespec.h>
|
||||
#include <support/xthread.h>
|
||||
|
||||
|
||||
static pthread_mutex_t mut = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
|
||||
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
|
||||
|
||||
|
||||
static int
|
||||
do_test_clock (clockid_t clockid)
|
||||
{
|
||||
/* Get the mutex. */
|
||||
xpthread_mutex_lock (&mut);
|
||||
|
||||
/* Waiting for the condition will fail. But we want the timeout here. */
|
||||
const struct timespec ts_now = xclock_now (clockid);
|
||||
const struct timespec ts_timeout =
|
||||
timespec_add (ts_now, make_timespec (0, 500000000));
|
||||
|
||||
/* In theory pthread_cond_clockwait could return zero here due to
|
||||
spurious wakeup. However that can't happen without a signal or an
|
||||
additional waiter. */
|
||||
TEST_COMPARE (pthread_cond_clockwait (&cond, &mut, clockid, &ts_timeout),
|
||||
ETIMEDOUT);
|
||||
|
||||
xpthread_mutex_unlock (&mut);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
do_test_clock (CLOCK_MONOTONIC);
|
||||
do_test_clock (CLOCK_REALTIME);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <support/test-driver.c>
|
@ -55,6 +55,10 @@ struct pthread_functions
|
||||
int (*ptr___pthread_cond_wait) (pthread_cond_t *, pthread_mutex_t *);
|
||||
int (*ptr___pthread_cond_timedwait) (pthread_cond_t *, pthread_mutex_t *,
|
||||
const struct timespec *);
|
||||
int (*ptr___pthread_cond_clockwait) (pthread_cond_t *,
|
||||
pthread_mutex_t *,
|
||||
clockid_t,
|
||||
const struct timespec *);
|
||||
int (*ptr___pthread_cond_broadcast_2_0) (pthread_cond_2_0_t *);
|
||||
int (*ptr___pthread_cond_destroy_2_0) (pthread_cond_2_0_t *);
|
||||
int (*ptr___pthread_cond_init_2_0) (pthread_cond_2_0_t *,
|
||||
|
@ -1003,6 +1003,21 @@ extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond,
|
||||
const struct timespec *__restrict __abstime)
|
||||
__nonnull ((1, 2, 3));
|
||||
|
||||
# ifdef __USE_GNU
|
||||
/* Wait for condition variable COND to be signaled or broadcast until
|
||||
ABSTIME measured by the specified clock. MUTEX is assumed to be
|
||||
locked before. CLOCK is the clock to use. ABSTIME is an absolute
|
||||
time specification against CLOCK's epoch.
|
||||
|
||||
This function is a cancellation point and therefore not marked with
|
||||
__THROW. */
|
||||
extern int pthread_cond_clockwait (pthread_cond_t *__restrict __cond,
|
||||
pthread_mutex_t *__restrict __mutex,
|
||||
__clockid_t __clock_id,
|
||||
const struct timespec *__restrict __abstime)
|
||||
__nonnull ((1, 2, 4));
|
||||
# endif
|
||||
|
||||
/* Functions for handling condition variable attributes. */
|
||||
|
||||
/* Initialize condition variable attribute ATTR. */
|
||||
|
@ -241,4 +241,5 @@ GLIBC_2.28 tss_create F
|
||||
GLIBC_2.28 tss_delete F
|
||||
GLIBC_2.28 tss_get F
|
||||
GLIBC_2.28 tss_set F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
|
@ -254,6 +254,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_getaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setschedprio F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
GLIBC_2.4 pthread_mutex_consistent_np F
|
||||
GLIBC_2.4 pthread_mutex_getprioceiling F
|
||||
|
@ -27,6 +27,7 @@ GLIBC_2.28 tss_create F
|
||||
GLIBC_2.28 tss_delete F
|
||||
GLIBC_2.28 tss_get F
|
||||
GLIBC_2.28 tss_set F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
GLIBC_2.4 _IO_flockfile F
|
||||
GLIBC_2.4 _IO_ftrylockfile F
|
||||
|
@ -233,4 +233,5 @@ GLIBC_2.29 tss_set F
|
||||
GLIBC_2.29 wait F
|
||||
GLIBC_2.29 waitpid F
|
||||
GLIBC_2.29 write F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
|
@ -243,6 +243,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_getaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setschedprio F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
GLIBC_2.4 pthread_mutex_consistent_np F
|
||||
GLIBC_2.4 pthread_mutex_getprioceiling F
|
||||
|
@ -252,6 +252,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_getaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setschedprio F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
GLIBC_2.4 pthread_mutex_consistent_np F
|
||||
GLIBC_2.4 pthread_mutex_getprioceiling F
|
||||
|
@ -245,6 +245,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_getaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setschedprio F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
GLIBC_2.4 pthread_mutex_consistent_np F
|
||||
GLIBC_2.4 pthread_mutex_getprioceiling F
|
||||
|
@ -27,6 +27,7 @@ GLIBC_2.28 tss_create F
|
||||
GLIBC_2.28 tss_delete F
|
||||
GLIBC_2.28 tss_get F
|
||||
GLIBC_2.28 tss_set F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
GLIBC_2.4 _IO_flockfile F
|
||||
GLIBC_2.4 _IO_ftrylockfile F
|
||||
|
@ -252,6 +252,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_getaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setschedprio F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
GLIBC_2.4 pthread_mutex_consistent_np F
|
||||
GLIBC_2.4 pthread_mutex_getprioceiling F
|
||||
|
@ -241,4 +241,5 @@ GLIBC_2.28 tss_create F
|
||||
GLIBC_2.28 tss_delete F
|
||||
GLIBC_2.28 tss_get F
|
||||
GLIBC_2.28 tss_set F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
|
@ -253,6 +253,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_getaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setschedprio F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
GLIBC_2.4 pthread_mutex_consistent_np F
|
||||
GLIBC_2.4 pthread_mutex_getprioceiling F
|
||||
|
@ -253,6 +253,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_getaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setschedprio F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
GLIBC_2.4 pthread_mutex_consistent_np F
|
||||
GLIBC_2.4 pthread_mutex_getprioceiling F
|
||||
|
@ -241,4 +241,5 @@ GLIBC_2.28 tss_create F
|
||||
GLIBC_2.28 tss_delete F
|
||||
GLIBC_2.28 tss_get F
|
||||
GLIBC_2.28 tss_set F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
|
@ -254,6 +254,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setschedprio F
|
||||
GLIBC_2.3.4 siglongjmp F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
GLIBC_2.4 pthread_mutex_consistent_np F
|
||||
GLIBC_2.4 pthread_mutex_getprioceiling F
|
||||
|
@ -244,6 +244,7 @@ GLIBC_2.3.4 pthread_getaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setschedprio F
|
||||
GLIBC_2.3.4 siglongjmp F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
GLIBC_2.4 pthread_mutex_consistent_np F
|
||||
GLIBC_2.4 pthread_mutex_getprioceiling F
|
||||
|
@ -241,4 +241,5 @@ GLIBC_2.28 tss_create F
|
||||
GLIBC_2.28 tss_delete F
|
||||
GLIBC_2.28 tss_get F
|
||||
GLIBC_2.28 tss_set F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
|
@ -235,4 +235,5 @@ GLIBC_2.28 tss_create F
|
||||
GLIBC_2.28 tss_delete F
|
||||
GLIBC_2.28 tss_get F
|
||||
GLIBC_2.28 tss_set F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
|
@ -254,6 +254,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_getaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setschedprio F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
GLIBC_2.4 pthread_mutex_consistent_np F
|
||||
GLIBC_2.4 pthread_mutex_getprioceiling F
|
||||
|
@ -245,6 +245,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_getaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setschedprio F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
GLIBC_2.4 pthread_mutex_consistent_np F
|
||||
GLIBC_2.4 pthread_mutex_getprioceiling F
|
||||
|
@ -243,6 +243,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_getaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setschedprio F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
GLIBC_2.4 pthread_mutex_consistent_np F
|
||||
GLIBC_2.4 pthread_mutex_getprioceiling F
|
||||
|
@ -254,6 +254,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_getaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setschedprio F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
GLIBC_2.4 pthread_mutex_consistent_np F
|
||||
GLIBC_2.4 pthread_mutex_getprioceiling F
|
||||
|
@ -245,6 +245,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_getaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setschedprio F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
GLIBC_2.4 pthread_mutex_consistent_np F
|
||||
GLIBC_2.4 pthread_mutex_getprioceiling F
|
||||
|
@ -243,6 +243,7 @@ GLIBC_2.3.4 pthread_attr_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_getaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setaffinity_np F
|
||||
GLIBC_2.3.4 pthread_setschedprio F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
GLIBC_2.4 pthread_mutex_consistent_np F
|
||||
GLIBC_2.4 pthread_mutex_getprioceiling F
|
||||
|
@ -241,4 +241,5 @@ GLIBC_2.28 tss_create F
|
||||
GLIBC_2.28 tss_delete F
|
||||
GLIBC_2.28 tss_get F
|
||||
GLIBC_2.28 tss_set F
|
||||
GLIBC_2.30 pthread_cond_clockwait F
|
||||
GLIBC_2.30 sem_clockwait F
|
||||
|
Loading…
Reference in New Issue
Block a user