nptl: Add POSIX-proposed sem_clockwait

Add:

 int sem_clockwait (sem_t *sem, clockid_t clock, const struct timespec
*abstime)

which behaves just like sem_timedwait, but measures abstime against the
specified clock. Currently supports CLOCK_REALTIME and CLOCK_MONOTONIC
and sets errno == EINVAL if any other clock is specified.

	* nptl/sem_waitcommon.c (do_futex_wait, __new_sem_wait_slow): Add
	clockid parameters to indicate the clock which abstime should be
	measured against.
	* nptl/sem_timedwait.c (sem_timedwait), nptl/sem_wait.c
	(__new_sem_wait): Pass CLOCK_REALTIME as clockid to
	__new_sem_wait_slow.
	* nptl/sem_clockwait.c: New file to implement sem_clockwait based
	on sem_timedwait.c.
	* nptl/Makefile: Add sem_clockwait.c source file. Add CFLAGS for
	sem_clockwait.c to match those used for sem_timedwait.c.
	* sysdeps/pthread/semaphore.h: Add sem_clockwait.
	* nptl/Versions (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-sem17.c: Add new test for passing invalid clock to
	sem_clockwait.
	* nptl/tst-sem13.c, nptl/tst-sem5.c: Modify existing sem_timedwait
	tests to also test sem_clockwait.
	* manual/threads.texi: Document sem_clockwait.

Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
This commit is contained in:
Mike Crowe 2019-06-21 15:57:41 +00:00 committed by Adhemerval Zanella
parent 99d01ffcc3
commit 6615f77978
36 changed files with 293 additions and 20 deletions

View File

@ -1,5 +1,64 @@
2019-07-12 Mike Crowe <mac@mcrowe.com> 2019-07-12 Mike Crowe <mac@mcrowe.com>
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
clockid parameters to indicate the clock which abstime should be
measured against.
* nptl/sem_timedwait.c (sem_timedwait), nptl/sem_wait.c
(__new_sem_wait): Pass CLOCK_REALTIME as clockid to
__new_sem_wait_slow.
* nptl/sem_clockwait.c: New file to implement sem_clockwait based
on sem_timedwait.c.
* nptl/Makefile: Add sem_clockwait.c source file. Add CFLAGS for
sem_clockwait.c to match those used for sem_timedwait.c.
* sysdeps/pthread/semaphore.h: Add sem_clockwait.
* nptl/Versions (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-sem17.c: Add new test for passing invalid clock to
sem_clockwait.
* nptl/tst-sem13.c, nptl/tst-sem5.c: Modify existing sem_timedwait
tests to also test sem_clockwait.
* manual/threads.texi: Document sem_clockwait.
nptl: Add clockid parameter to futex timed wait calls nptl: Add clockid parameter to futex timed wait calls
* sysdeps/nptl/lowlevellock-futex.h, * sysdeps/nptl/lowlevellock-futex.h,
sysdeps/unix/sysv/linux/lowlevellock-futex.h: Replace sysdeps/unix/sysv/linux/lowlevellock-futex.h: Replace

View File

@ -669,6 +669,16 @@ The system does not have sufficient memory.
@end table @end table
@end deftypefun @end deftypefun
@comment semaphore.h
@comment POSIX-proposed
@deftypefun int sem_clockwait (sem_t *@var{sem}, clockid_t @var{clockid},
const struct timespec *@var{abstime})
Behaves like @code{sem_timedwait} except the time @var{abstime} is measured
against the clock specified by @var{clockid} rather than
@code{CLOCK_REALTIME}. Currently, @var{clockid} must be either
@code{CLOCK_MONOTONIC} or @code{CLOCK_REALTIME}.
@end deftypefun
@c FIXME these are undocumented: @c FIXME these are undocumented:
@c pthread_atfork @c pthread_atfork
@c pthread_attr_destroy @c pthread_attr_destroy

View File

@ -113,7 +113,7 @@ libpthread-routines = nptl-init nptlfreeres vars events version pt-interp \
sem_init sem_destroy \ sem_init sem_destroy \
sem_open sem_close sem_unlink \ sem_open sem_close sem_unlink \
sem_getvalue \ sem_getvalue \
sem_wait sem_timedwait sem_post \ sem_wait sem_timedwait sem_clockwait sem_post \
cleanup cleanup_defer cleanup_compat \ cleanup cleanup_defer cleanup_compat \
cleanup_defer_compat unwind \ cleanup_defer_compat unwind \
pt-longjmp pt-cleanup\ pt-longjmp pt-cleanup\
@ -194,6 +194,7 @@ CFLAGS-pthread_once.c += $(uses-callbacks) -fexceptions \
CFLAGS-pthread_cond_wait.c += -fexceptions -fasynchronous-unwind-tables CFLAGS-pthread_cond_wait.c += -fexceptions -fasynchronous-unwind-tables
CFLAGS-sem_wait.c += -fexceptions -fasynchronous-unwind-tables CFLAGS-sem_wait.c += -fexceptions -fasynchronous-unwind-tables
CFLAGS-sem_timedwait.c += -fexceptions -fasynchronous-unwind-tables CFLAGS-sem_timedwait.c += -fexceptions -fasynchronous-unwind-tables
CFLAGS-sem_clockwait.c = -fexceptions -fasynchronous-unwind-tables
# These are the function wrappers we have to duplicate here. # These are the function wrappers we have to duplicate here.
CFLAGS-fcntl.c += -fexceptions -fasynchronous-unwind-tables CFLAGS-fcntl.c += -fexceptions -fasynchronous-unwind-tables
@ -263,7 +264,7 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
tst-key1 tst-key2 tst-key3 tst-key4 \ tst-key1 tst-key2 tst-key3 tst-key4 \
tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem5 tst-sem6 tst-sem7 \ tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem5 tst-sem6 tst-sem7 \
tst-sem8 tst-sem9 tst-sem10 tst-sem14 \ tst-sem8 tst-sem9 tst-sem10 tst-sem14 \
tst-sem15 tst-sem16 \ tst-sem15 tst-sem16 tst-sem17 \
tst-barrier1 tst-barrier2 tst-barrier3 tst-barrier4 \ tst-barrier1 tst-barrier2 tst-barrier3 tst-barrier4 \
tst-align tst-align3 \ tst-align tst-align3 \
tst-basic1 tst-basic2 tst-basic3 tst-basic4 tst-basic5 tst-basic6 \ tst-basic1 tst-basic2 tst-basic3 tst-basic4 tst-basic5 tst-basic6 \

View File

@ -276,6 +276,10 @@ libpthread {
cnd_timedwait; cnd_wait; tss_create; tss_delete; tss_get; tss_set; cnd_timedwait; cnd_wait; tss_create; tss_delete; tss_get; tss_set;
} }
GLIBC_2.30 {
sem_clockwait;
}
GLIBC_PRIVATE { GLIBC_PRIVATE {
__pthread_initialize_minimal; __pthread_initialize_minimal;
__pthread_clock_gettime; __pthread_clock_settime; __pthread_clock_gettime; __pthread_clock_settime;

45
nptl/sem_clockwait.c Normal file
View File

@ -0,0 +1,45 @@
/* sem_clockwait -- wait on a semaphore with timeout using the specified
clock.
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 "sem_waitcommon.c"
int
sem_clockwait (sem_t *sem, clockid_t clockid,
const struct timespec *abstime)
{
/* Check that supplied clockid is one we support, even if we don't end up
waiting. */
if (!futex_abstimed_supported_clockid (clockid))
{
__set_errno (EINVAL);
return -1;
}
if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
{
__set_errno (EINVAL);
return -1;
}
if (__new_sem_wait_fast ((struct new_sem *) sem, 0) == 0)
return 0;
else
return __new_sem_wait_slow ((struct new_sem *) sem, clockid, abstime);
}

View File

@ -36,5 +36,6 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime)
if (__new_sem_wait_fast ((struct new_sem *) sem, 0) == 0) if (__new_sem_wait_fast ((struct new_sem *) sem, 0) == 0)
return 0; return 0;
else else
return __new_sem_wait_slow((struct new_sem *) sem, abstime); return __new_sem_wait_slow ((struct new_sem *) sem,
CLOCK_REALTIME, abstime);
} }

View File

@ -39,7 +39,8 @@ __new_sem_wait (sem_t *sem)
if (__new_sem_wait_fast ((struct new_sem *) sem, 0) == 0) if (__new_sem_wait_fast ((struct new_sem *) sem, 0) == 0)
return 0; return 0;
else else
return __new_sem_wait_slow((struct new_sem *) sem, NULL); return __new_sem_wait_slow ((struct new_sem *) sem,
CLOCK_REALTIME, NULL);
} }
versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1); versioned_symbol (libpthread, __new_sem_wait, sem_wait, GLIBC_2_1);

View File

@ -103,19 +103,19 @@ __sem_wait_cleanup (void *arg)
users don't seem to need it. */ users don't seem to need it. */
static int static int
__attribute__ ((noinline)) __attribute__ ((noinline))
do_futex_wait (struct new_sem *sem, const struct timespec *abstime) do_futex_wait (struct new_sem *sem, clockid_t clockid,
const struct timespec *abstime)
{ {
int err; int err;
#if __HAVE_64B_ATOMICS #if __HAVE_64B_ATOMICS
err = futex_abstimed_wait_cancelable ( err = futex_abstimed_wait_cancelable (
(unsigned int *) &sem->data + SEM_VALUE_OFFSET, 0, (unsigned int *) &sem->data + SEM_VALUE_OFFSET, 0,
CLOCK_REALTIME, abstime, clockid, abstime,
sem->private); sem->private);
#else #else
err = futex_abstimed_wait_cancelable (&sem->value, SEM_NWAITERS_MASK, err = futex_abstimed_wait_cancelable (&sem->value, SEM_NWAITERS_MASK,
CLOCK_REALTIME, abstime, clockid, abstime, sem->private);
sem->private);
#endif #endif
return err; return err;
@ -162,7 +162,8 @@ __new_sem_wait_fast (struct new_sem *sem, int definitive_result)
/* Slow path that blocks. */ /* Slow path that blocks. */
static int static int
__attribute__ ((noinline)) __attribute__ ((noinline))
__new_sem_wait_slow (struct new_sem *sem, const struct timespec *abstime) __new_sem_wait_slow (struct new_sem *sem, clockid_t clockid,
const struct timespec *abstime)
{ {
int err = 0; int err = 0;
@ -180,7 +181,7 @@ __new_sem_wait_slow (struct new_sem *sem, const struct timespec *abstime)
/* If there is no token available, sleep until there is. */ /* If there is no token available, sleep until there is. */
if ((d & SEM_VALUE_MASK) == 0) if ((d & SEM_VALUE_MASK) == 0)
{ {
err = do_futex_wait (sem, abstime); err = do_futex_wait (sem, clockid, abstime);
/* A futex return value of 0 or EAGAIN is due to a real or spurious /* A futex return value of 0 or EAGAIN is due to a real or spurious
wake-up, or due to a change in the number of tokens. We retry in wake-up, or due to a change in the number of tokens. We retry in
these cases. these cases.
@ -281,7 +282,7 @@ __new_sem_wait_slow (struct new_sem *sem, const struct timespec *abstime)
if ((v >> SEM_VALUE_SHIFT) == 0) if ((v >> SEM_VALUE_SHIFT) == 0)
{ {
/* See __HAVE_64B_ATOMICS variant. */ /* See __HAVE_64B_ATOMICS variant. */
err = do_futex_wait(sem, abstime); err = do_futex_wait (sem, clockid, abstime);
if (err == ETIMEDOUT || err == EINTR) if (err == ETIMEDOUT || err == EINTR)
{ {
__set_errno (err); __set_errno (err);

View File

@ -6,9 +6,14 @@
#include <internaltypes.h> #include <internaltypes.h>
#include <support/check.h> #include <support/check.h>
/* A bogus clock value that tells run_test to use sem_timedwait rather than
sem_clockwait. */
#define CLOCK_USE_TIMEDWAIT (-1)
static int typedef int (*waitfn_t)(sem_t *, struct timespec *);
do_test (void)
static void
do_test_wait (waitfn_t waitfn, const char *fnname)
{ {
union union
{ {
@ -16,11 +21,13 @@ do_test (void)
struct new_sem ns; struct new_sem ns;
} u; } u;
printf ("do_test_wait: %s\n", fnname);
TEST_COMPARE (sem_init (&u.s, 0, 0), 0); TEST_COMPARE (sem_init (&u.s, 0, 0), 0);
struct timespec ts = { 0, 1000000001 }; /* Invalid. */ struct timespec ts = { 0, 1000000001 }; /* Invalid. */
errno = 0; errno = 0;
TEST_VERIFY_EXIT (sem_timedwait (&u.s, &ts) < 0); TEST_VERIFY_EXIT (waitfn (&u.s, &ts) < 0);
TEST_COMPARE (errno, EINVAL); TEST_COMPARE (errno, EINVAL);
#if __HAVE_64B_ATOMICS #if __HAVE_64B_ATOMICS
@ -33,7 +40,7 @@ do_test (void)
ts.tv_sec = /* Invalid. */ -2; ts.tv_sec = /* Invalid. */ -2;
ts.tv_nsec = 0; ts.tv_nsec = 0;
errno = 0; errno = 0;
TEST_VERIFY_EXIT (sem_timedwait (&u.s, &ts) < 0); TEST_VERIFY_EXIT (waitfn (&u.s, &ts) < 0);
TEST_COMPARE (errno, ETIMEDOUT); TEST_COMPARE (errno, ETIMEDOUT);
#if __HAVE_64B_ATOMICS #if __HAVE_64B_ATOMICS
nwaiters = (u.ns.data >> SEM_NWAITERS_SHIFT); nwaiters = (u.ns.data >> SEM_NWAITERS_SHIFT);
@ -41,7 +48,31 @@ do_test (void)
nwaiters = u.ns.nwaiters; nwaiters = u.ns.nwaiters;
#endif #endif
TEST_COMPARE (nwaiters, 0); TEST_COMPARE (nwaiters, 0);
}
int test_sem_timedwait (sem_t *sem, struct timespec *ts)
{
return sem_timedwait (sem, ts);
}
int test_sem_clockwait_monotonic (sem_t *sem, struct timespec *ts)
{
return sem_clockwait (sem, CLOCK_MONOTONIC, ts);
}
int test_sem_clockwait_realtime (sem_t *sem, struct timespec *ts)
{
return sem_clockwait (sem, CLOCK_REALTIME, ts);
}
static int do_test (void)
{
do_test_wait (&test_sem_timedwait,
"sem_timedwait");
do_test_wait (&test_sem_clockwait_monotonic,
"sem_clockwait(monotonic)");
do_test_wait (&test_sem_clockwait_realtime,
"sem_clockwait(realtime)");
return 0; return 0;
} }

76
nptl/tst-sem17.c Normal file
View File

@ -0,0 +1,76 @@
/* Test unsupported/bad clocks passed to sem_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 <semaphore.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <sys/time.h>
#include <support/check.h>
#include <support/timespec.h>
#define NOT_A_VALID_CLOCK 123456
static int
do_test (void)
{
sem_t s;
TEST_COMPARE (sem_init (&s, 0, 1), 0);
const struct timespec ts = make_timespec (0, 0);
/* These clocks are meaningless to sem_clockwait. */
#if defined(CLOCK_PROCESS_CPUTIME_ID)
TEST_COMPARE (sem_clockwait (&s, CLOCK_PROCESS_CPUTIME_ID, &ts), -1);
TEST_COMPARE (errno, EINVAL);
#endif
#if defined(CLOCK_THREAD_CPUTIME_ID)
TEST_COMPARE (sem_clockwait (&s, CLOCK_THREAD_CPUTIME_ID, &ts), -1);
TEST_COMPARE (errno, EINVAL);
#endif
/* These clocks might be meaningful, but are currently unsupported
by pthread_cond_clockwait. */
#if defined(CLOCK_REALTIME_COARSE)
TEST_COMPARE (sem_clockwait (&s, CLOCK_REALTIME_COARSE, &ts), -1);
TEST_COMPARE (errno, EINVAL);
#endif
#if defined(CLOCK_MONOTONIC_RAW)
TEST_COMPARE (sem_clockwait (&s, CLOCK_MONOTONIC_RAW, &ts), -1);
TEST_COMPARE (errno, EINVAL);
#endif
#if defined(CLOCK_MONOTONIC_COARSE)
TEST_COMPARE (sem_clockwait (&s, CLOCK_MONOTONIC_COARSE, &ts), -1);
TEST_COMPARE (errno, EINVAL);
#endif
#if defined(CLOCK_BOOTTIME)
TEST_COMPARE (sem_clockwait (&s, CLOCK_BOOTTIME, &ts), -1);
TEST_COMPARE (errno, EINVAL);
#endif
/* This is a completely invalid clock. */
TEST_COMPARE (sem_clockwait (&s, NOT_A_VALID_CLOCK, &ts), -1);
TEST_COMPARE (errno, EINVAL);
return 0;
}
#include <support/test-driver.c>

View File

@ -25,10 +25,15 @@
#include <support/timespec.h> #include <support/timespec.h>
#include <support/xtime.h> #include <support/xtime.h>
/* A bogus clock value that tells run_test to use sem_timedwait rather than
sem_clockwait. */
#define CLOCK_USE_TIMEDWAIT (-1)
static int static void
do_test (void) do_test_clock (clockid_t clockid)
{ {
const clockid_t clockid_for_get =
clockid == CLOCK_USE_TIMEDWAIT ? CLOCK_REALTIME : clockid;
sem_t s; sem_t s;
struct timespec ts; struct timespec ts;
@ -36,14 +41,22 @@ do_test (void)
TEST_COMPARE (TEMP_FAILURE_RETRY (sem_wait (&s)), 0); TEST_COMPARE (TEMP_FAILURE_RETRY (sem_wait (&s)), 0);
/* We wait for half a second. */ /* We wait for half a second. */
xclock_gettime (CLOCK_REALTIME, &ts); xclock_gettime (clockid_for_get, &ts);
ts = timespec_add (ts, make_timespec (0, TIMESPEC_HZ/2)); ts = timespec_add (ts, make_timespec (0, TIMESPEC_HZ/2));
errno = 0; errno = 0;
TEST_COMPARE (TEMP_FAILURE_RETRY (sem_timedwait (&s, &ts)), -1); TEST_COMPARE (TEMP_FAILURE_RETRY ((clockid == CLOCK_USE_TIMEDWAIT)
? sem_timedwait (&s, &ts)
: sem_clockwait (&s, clockid, &ts)), -1);
TEST_COMPARE (errno, ETIMEDOUT); TEST_COMPARE (errno, ETIMEDOUT);
TEST_TIMESPEC_NOW_OR_AFTER (CLOCK_REALTIME, ts); TEST_TIMESPEC_NOW_OR_AFTER (clockid_for_get, ts);
}
static int do_test (void)
{
do_test_clock (CLOCK_USE_TIMEDWAIT);
do_test_clock (CLOCK_REALTIME);
do_test_clock (CLOCK_MONOTONIC);
return 0; return 0;
} }

View File

@ -64,6 +64,13 @@ extern int sem_timedwait (sem_t *__restrict __sem,
__nonnull ((1, 2)); __nonnull ((1, 2));
#endif #endif
#ifdef __USE_GNU
extern int sem_clockwait (sem_t *__restrict __sem,
clockid_t clock,
const struct timespec *__restrict __abstime)
__nonnull ((1, 3));
#endif
/* Test whether SEM is posted. */ /* Test whether SEM is posted. */
extern int sem_trywait (sem_t *__sem) __THROWNL __nonnull ((1)); extern int sem_trywait (sem_t *__sem) __THROWNL __nonnull ((1));

View File

@ -241,3 +241,4 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F GLIBC_2.28 tss_set F
GLIBC_2.30 sem_clockwait F

View File

@ -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_getaffinity_np F
GLIBC_2.3.4 pthread_setaffinity_np F GLIBC_2.3.4 pthread_setaffinity_np F
GLIBC_2.3.4 pthread_setschedprio F GLIBC_2.3.4 pthread_setschedprio F
GLIBC_2.30 sem_clockwait F
GLIBC_2.4 pthread_mutex_consistent_np F GLIBC_2.4 pthread_mutex_consistent_np F
GLIBC_2.4 pthread_mutex_getprioceiling F GLIBC_2.4 pthread_mutex_getprioceiling F
GLIBC_2.4 pthread_mutex_setprioceiling F GLIBC_2.4 pthread_mutex_setprioceiling F

View File

@ -27,6 +27,7 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F GLIBC_2.28 tss_set F
GLIBC_2.30 sem_clockwait F
GLIBC_2.4 _IO_flockfile F GLIBC_2.4 _IO_flockfile F
GLIBC_2.4 _IO_ftrylockfile F GLIBC_2.4 _IO_ftrylockfile F
GLIBC_2.4 _IO_funlockfile F GLIBC_2.4 _IO_funlockfile F

View File

@ -233,3 +233,4 @@ GLIBC_2.29 tss_set F
GLIBC_2.29 wait F GLIBC_2.29 wait F
GLIBC_2.29 waitpid F GLIBC_2.29 waitpid F
GLIBC_2.29 write F GLIBC_2.29 write F
GLIBC_2.30 sem_clockwait F

View File

@ -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_getaffinity_np F
GLIBC_2.3.4 pthread_setaffinity_np F GLIBC_2.3.4 pthread_setaffinity_np F
GLIBC_2.3.4 pthread_setschedprio F GLIBC_2.3.4 pthread_setschedprio F
GLIBC_2.30 sem_clockwait F
GLIBC_2.4 pthread_mutex_consistent_np F GLIBC_2.4 pthread_mutex_consistent_np F
GLIBC_2.4 pthread_mutex_getprioceiling F GLIBC_2.4 pthread_mutex_getprioceiling F
GLIBC_2.4 pthread_mutex_setprioceiling F GLIBC_2.4 pthread_mutex_setprioceiling F

View File

@ -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_getaffinity_np F
GLIBC_2.3.4 pthread_setaffinity_np F GLIBC_2.3.4 pthread_setaffinity_np F
GLIBC_2.3.4 pthread_setschedprio F GLIBC_2.3.4 pthread_setschedprio F
GLIBC_2.30 sem_clockwait F
GLIBC_2.4 pthread_mutex_consistent_np F GLIBC_2.4 pthread_mutex_consistent_np F
GLIBC_2.4 pthread_mutex_getprioceiling F GLIBC_2.4 pthread_mutex_getprioceiling F
GLIBC_2.4 pthread_mutex_setprioceiling F GLIBC_2.4 pthread_mutex_setprioceiling F

View File

@ -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_getaffinity_np F
GLIBC_2.3.4 pthread_setaffinity_np F GLIBC_2.3.4 pthread_setaffinity_np F
GLIBC_2.3.4 pthread_setschedprio F GLIBC_2.3.4 pthread_setschedprio F
GLIBC_2.30 sem_clockwait F
GLIBC_2.4 pthread_mutex_consistent_np F GLIBC_2.4 pthread_mutex_consistent_np F
GLIBC_2.4 pthread_mutex_getprioceiling F GLIBC_2.4 pthread_mutex_getprioceiling F
GLIBC_2.4 pthread_mutex_setprioceiling F GLIBC_2.4 pthread_mutex_setprioceiling F

View File

@ -27,6 +27,7 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F GLIBC_2.28 tss_set F
GLIBC_2.30 sem_clockwait F
GLIBC_2.4 _IO_flockfile F GLIBC_2.4 _IO_flockfile F
GLIBC_2.4 _IO_ftrylockfile F GLIBC_2.4 _IO_ftrylockfile F
GLIBC_2.4 _IO_funlockfile F GLIBC_2.4 _IO_funlockfile F

View File

@ -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_getaffinity_np F
GLIBC_2.3.4 pthread_setaffinity_np F GLIBC_2.3.4 pthread_setaffinity_np F
GLIBC_2.3.4 pthread_setschedprio F GLIBC_2.3.4 pthread_setschedprio F
GLIBC_2.30 sem_clockwait F
GLIBC_2.4 pthread_mutex_consistent_np F GLIBC_2.4 pthread_mutex_consistent_np F
GLIBC_2.4 pthread_mutex_getprioceiling F GLIBC_2.4 pthread_mutex_getprioceiling F
GLIBC_2.4 pthread_mutex_setprioceiling F GLIBC_2.4 pthread_mutex_setprioceiling F

View File

@ -241,3 +241,4 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F GLIBC_2.28 tss_set F
GLIBC_2.30 sem_clockwait F

View File

@ -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_getaffinity_np F
GLIBC_2.3.4 pthread_setaffinity_np F GLIBC_2.3.4 pthread_setaffinity_np F
GLIBC_2.3.4 pthread_setschedprio F GLIBC_2.3.4 pthread_setschedprio F
GLIBC_2.30 sem_clockwait F
GLIBC_2.4 pthread_mutex_consistent_np F GLIBC_2.4 pthread_mutex_consistent_np F
GLIBC_2.4 pthread_mutex_getprioceiling F GLIBC_2.4 pthread_mutex_getprioceiling F
GLIBC_2.4 pthread_mutex_setprioceiling F GLIBC_2.4 pthread_mutex_setprioceiling F

View File

@ -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_getaffinity_np F
GLIBC_2.3.4 pthread_setaffinity_np F GLIBC_2.3.4 pthread_setaffinity_np F
GLIBC_2.3.4 pthread_setschedprio F GLIBC_2.3.4 pthread_setschedprio F
GLIBC_2.30 sem_clockwait F
GLIBC_2.4 pthread_mutex_consistent_np F GLIBC_2.4 pthread_mutex_consistent_np F
GLIBC_2.4 pthread_mutex_getprioceiling F GLIBC_2.4 pthread_mutex_getprioceiling F
GLIBC_2.4 pthread_mutex_setprioceiling F GLIBC_2.4 pthread_mutex_setprioceiling F

View File

@ -241,3 +241,4 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F GLIBC_2.28 tss_set F
GLIBC_2.30 sem_clockwait F

View File

@ -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_setaffinity_np F
GLIBC_2.3.4 pthread_setschedprio F GLIBC_2.3.4 pthread_setschedprio F
GLIBC_2.3.4 siglongjmp F GLIBC_2.3.4 siglongjmp F
GLIBC_2.30 sem_clockwait F
GLIBC_2.4 pthread_mutex_consistent_np F GLIBC_2.4 pthread_mutex_consistent_np F
GLIBC_2.4 pthread_mutex_getprioceiling F GLIBC_2.4 pthread_mutex_getprioceiling F
GLIBC_2.4 pthread_mutex_setprioceiling F GLIBC_2.4 pthread_mutex_setprioceiling F

View File

@ -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_setaffinity_np F
GLIBC_2.3.4 pthread_setschedprio F GLIBC_2.3.4 pthread_setschedprio F
GLIBC_2.3.4 siglongjmp F GLIBC_2.3.4 siglongjmp F
GLIBC_2.30 sem_clockwait F
GLIBC_2.4 pthread_mutex_consistent_np F GLIBC_2.4 pthread_mutex_consistent_np F
GLIBC_2.4 pthread_mutex_getprioceiling F GLIBC_2.4 pthread_mutex_getprioceiling F
GLIBC_2.4 pthread_mutex_setprioceiling F GLIBC_2.4 pthread_mutex_setprioceiling F

View File

@ -241,3 +241,4 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F GLIBC_2.28 tss_set F
GLIBC_2.30 sem_clockwait F

View File

@ -235,3 +235,4 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F GLIBC_2.28 tss_set F
GLIBC_2.30 sem_clockwait F

View File

@ -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_getaffinity_np F
GLIBC_2.3.4 pthread_setaffinity_np F GLIBC_2.3.4 pthread_setaffinity_np F
GLIBC_2.3.4 pthread_setschedprio F GLIBC_2.3.4 pthread_setschedprio F
GLIBC_2.30 sem_clockwait F
GLIBC_2.4 pthread_mutex_consistent_np F GLIBC_2.4 pthread_mutex_consistent_np F
GLIBC_2.4 pthread_mutex_getprioceiling F GLIBC_2.4 pthread_mutex_getprioceiling F
GLIBC_2.4 pthread_mutex_setprioceiling F GLIBC_2.4 pthread_mutex_setprioceiling F

View File

@ -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_getaffinity_np F
GLIBC_2.3.4 pthread_setaffinity_np F GLIBC_2.3.4 pthread_setaffinity_np F
GLIBC_2.3.4 pthread_setschedprio F GLIBC_2.3.4 pthread_setschedprio F
GLIBC_2.30 sem_clockwait F
GLIBC_2.4 pthread_mutex_consistent_np F GLIBC_2.4 pthread_mutex_consistent_np F
GLIBC_2.4 pthread_mutex_getprioceiling F GLIBC_2.4 pthread_mutex_getprioceiling F
GLIBC_2.4 pthread_mutex_setprioceiling F GLIBC_2.4 pthread_mutex_setprioceiling F

View File

@ -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_getaffinity_np F
GLIBC_2.3.4 pthread_setaffinity_np F GLIBC_2.3.4 pthread_setaffinity_np F
GLIBC_2.3.4 pthread_setschedprio F GLIBC_2.3.4 pthread_setschedprio F
GLIBC_2.30 sem_clockwait F
GLIBC_2.4 pthread_mutex_consistent_np F GLIBC_2.4 pthread_mutex_consistent_np F
GLIBC_2.4 pthread_mutex_getprioceiling F GLIBC_2.4 pthread_mutex_getprioceiling F
GLIBC_2.4 pthread_mutex_setprioceiling F GLIBC_2.4 pthread_mutex_setprioceiling F

View File

@ -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_getaffinity_np F
GLIBC_2.3.4 pthread_setaffinity_np F GLIBC_2.3.4 pthread_setaffinity_np F
GLIBC_2.3.4 pthread_setschedprio F GLIBC_2.3.4 pthread_setschedprio F
GLIBC_2.30 sem_clockwait F
GLIBC_2.4 pthread_mutex_consistent_np F GLIBC_2.4 pthread_mutex_consistent_np F
GLIBC_2.4 pthread_mutex_getprioceiling F GLIBC_2.4 pthread_mutex_getprioceiling F
GLIBC_2.4 pthread_mutex_setprioceiling F GLIBC_2.4 pthread_mutex_setprioceiling F

View File

@ -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_getaffinity_np F
GLIBC_2.3.4 pthread_setaffinity_np F GLIBC_2.3.4 pthread_setaffinity_np F
GLIBC_2.3.4 pthread_setschedprio F GLIBC_2.3.4 pthread_setschedprio F
GLIBC_2.30 sem_clockwait F
GLIBC_2.4 pthread_mutex_consistent_np F GLIBC_2.4 pthread_mutex_consistent_np F
GLIBC_2.4 pthread_mutex_getprioceiling F GLIBC_2.4 pthread_mutex_getprioceiling F
GLIBC_2.4 pthread_mutex_setprioceiling F GLIBC_2.4 pthread_mutex_setprioceiling F

View File

@ -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_getaffinity_np F
GLIBC_2.3.4 pthread_setaffinity_np F GLIBC_2.3.4 pthread_setaffinity_np F
GLIBC_2.3.4 pthread_setschedprio F GLIBC_2.3.4 pthread_setschedprio F
GLIBC_2.30 sem_clockwait F
GLIBC_2.4 pthread_mutex_consistent_np F GLIBC_2.4 pthread_mutex_consistent_np F
GLIBC_2.4 pthread_mutex_getprioceiling F GLIBC_2.4 pthread_mutex_getprioceiling F
GLIBC_2.4 pthread_mutex_setprioceiling F GLIBC_2.4 pthread_mutex_setprioceiling F

View File

@ -241,3 +241,4 @@ GLIBC_2.28 tss_create F
GLIBC_2.28 tss_delete F GLIBC_2.28 tss_delete F
GLIBC_2.28 tss_get F GLIBC_2.28 tss_get F
GLIBC_2.28 tss_set F GLIBC_2.28 tss_set F
GLIBC_2.30 sem_clockwait F