htl: Add clock variants

* htl/pt-join.c (__pthread_join): Move implementation to...
(__pthread_join_common): ... new function. Add try, timed and clock support.
(__pthread_join): Reimplement on top of __pthread_join_common.
(__pthread_tryjoin_np, __pthread_timedjoin_np, __pthread_clockjoin_np):
Implement on top of __pthread_join_common.
(pthread_tryjoin_np, pthread_timedjoin_np, pthread_clockjoin_np): New
aliases.

* hurd/hurdlock.c (__lll_abstimed_wait, __lll_abstimed_xwait,
__lll_abstimed_lock): Check for supported clock.

* sysdeps/htl/pt-cond-timedwait.c (__pthread_cond_timedwait_internal):
Add clockid parameter and support it.
(__pthread_cond_timedwait): Pass -1 as clockid.
(__pthread_cond_clockwait): New function.
(pthread_cond_clockwait): New alias.
* sysdeps/htl/pt-cond-wait.c (__pthread_cond_timedwait_internal): Update
prototype.
(__pthread_cond_wait): Pass -1 as clockid.

* sysdeps/htl/pt-rwlock-timedrdlock.c
(__pthread_rwlock_timedrdlock_internal): Add clockid parameter, and
support id.
(__pthread_rwlock_clockrdlock): New function.
(pthread_rwlock_clockrdlock): New alias.
* sysdeps/htl/pt-rwlock-rdlock.c (__pthread_rwlock_timedrdlock_internal): Update
prototype.
(__pthread_rwlock_rdlock): Pass -1 as clockid.

* sysdeps/htl/pt-rwlock-timedwrlock.c
(__pthread_rwlock_timedwrlock_internal): Add clockid parameter, and
support id.
(__pthread_rwlock_clockwrlock): New function.
(pthread_rwlock_clockwrlock): New alias.
* sysdeps/htl/pt-rwlock-wrlock.c (__pthread_rwlock_timedwrlock_internal): Update
prototype.
(__pthread_rwlock_wrlock): Pass -1 as clockid.

* sysdeps/mach/hurd/htl/pt-mutex-timedlock.c (__pthread_mutex_timedlock): Move implementation to
(__pthread_mutex_clocklock): New function with additional clockid
parameter and support it.
(pthread_mutex_clocklock): New alias.
(__pthread_mutex_timedlock): Reimplement on top of __pthread_mutex_clocklock.

* sysdeps/htl/pthread.h (pthread_tryjoin_np, pthread_timedjoin_np,
pthread_clockjoin_np, pthread_mutex_clocklock, pthread_cond_clockwait,
pthread_rwlock_clockrdlock, pthread_rwlock_clockwrlock): New prototypes.
* sysdeps/htl/pthreadP.h (__pthread_cond_clockwait): New prototype.

* htl/Versions (GLIBC_2.32): Add pthread_cond_clockwait,
pthread_mutex_clocklock, pthread_rwlock_clockrdlock, pthread_rwlock_clockwrlock,
pthread_tryjoin_np, pthread_timedjoin_np, pthread_clockjoin_np.
* sysdeps/mach/hurd/i386/libpthread.abilist (pthread_clockjoin_np,
pthread_cond_clockwait, pthread_mutex_clocklock, pthread_rwlock_clockrdlock,
pthread_rwlock_clockwrlock, pthread_timedjoin_np, pthread_tryjoin_np):
New functions.

* nptl/tst-abstime.c, nptl/tst-join10.c, nptl/tst-join11.c, nptl/tst-join12.c,
nptl/tst-join13.c, nptl/tst-join14.c, nptl/tst-join2.c, nptl/tst-join3.c,
nptl/tst-join8.c, nptl/tst-join9.c, nptl/tst-mutex-errorcheck.c,
nptl/tst-pthread-mutexattr.c, nptl/tst-mutex11.c, nptl/tst-mutex5.c,
nptl/tst-mutex7.c, nptl/tst-mutex7robus.c, nptl/tst-mutex9.c,
nptl/tst-rwlock12.c, nptl/tst-rwlock14.c: Move to sysdeps/pthread.
* sysdeps/pthread/tst-mutex8.c: Move back to nptl.
* nptl/Makefile (tests): Move tst-mutex5, tst-mutex7, tst-mutex7robust,
tst-mutex9, tst-mutex11, tst-rwlock12, tst-rwlock14, tst-join2, tst-join3,
tst-join8, tst-join9 tst-join10, tst-join11, tst-join12, tst-join13, tst-join14,
tst-abstime, tst-mutex-errorcheck, tst-pthread-mutexattr to ...
* sysdeps/pthread/Makefile (tests): ... here.
This commit is contained in:
Samuel Thibault 2020-05-26 00:09:11 +00:00
parent 02802fafcf
commit 28cada0418
35 changed files with 236 additions and 40 deletions

View File

@ -151,10 +151,17 @@ libpthread {
cnd_broadcast; cnd_destroy; cnd_init; cnd_signal; cnd_timedwait; cnd_wait; cnd_broadcast; cnd_destroy; cnd_init; cnd_signal; cnd_timedwait; cnd_wait;
tss_create; tss_delete; tss_get; tss_set; tss_create; tss_delete; tss_get; tss_set;
pthread_cond_clockwait;
pthread_mutexattr_getrobust; pthread_mutexattr_getrobust_np; pthread_mutexattr_getrobust; pthread_mutexattr_getrobust_np;
pthread_mutexattr_setrobust; pthread_mutexattr_setrobust_np; pthread_mutexattr_setrobust; pthread_mutexattr_setrobust_np;
pthread_mutex_consistent; pthread_mutex_consistent_np; pthread_mutex_consistent; pthread_mutex_consistent_np;
pthread_mutex_clocklock;
pthread_rwlock_clockrdlock; pthread_rwlock_clockwrlock;
pthread_tryjoin_np; pthread_timedjoin_np; pthread_clockjoin_np;
} }
GLIBC_PRIVATE { GLIBC_PRIVATE {

View File

@ -24,8 +24,10 @@
/* Make calling thread wait for termination of thread THREAD. Return /* Make calling thread wait for termination of thread THREAD. Return
the exit status of the thread in *STATUS. */ the exit status of the thread in *STATUS. */
int static int
__pthread_join (pthread_t thread, void **status) __pthread_join_common (pthread_t thread, void **status, int try,
clockid_t clockid,
const struct timespec *abstime)
{ {
struct __pthread *pthread; struct __pthread *pthread;
int err = 0; int err = 0;
@ -39,18 +41,30 @@ __pthread_join (pthread_t thread, void **status)
return EDEADLK; return EDEADLK;
__pthread_mutex_lock (&pthread->state_lock); __pthread_mutex_lock (&pthread->state_lock);
pthread_cleanup_push ((void (*)(void *)) __pthread_mutex_unlock,
&pthread->state_lock);
/* Rely on pthread_cond_wait being a cancellation point to make if (try == 0)
pthread_join one too. */ {
while (pthread->state == PTHREAD_JOINABLE) pthread_cleanup_push ((void (*)(void *)) __pthread_mutex_unlock,
__pthread_cond_wait (&pthread->state_cond, &pthread->state_lock); &pthread->state_lock);
pthread_cleanup_pop (0); /* Rely on pthread_cond_wait being a cancellation point to make
pthread_join one too. */
while (pthread->state == PTHREAD_JOINABLE && err != ETIMEDOUT)
err = __pthread_cond_clockwait (&pthread->state_cond,
&pthread->state_lock,
clockid, abstime);
pthread_cleanup_pop (0);
}
switch (pthread->state) switch (pthread->state)
{ {
case PTHREAD_JOINABLE:
__pthread_mutex_unlock (&pthread->state_lock);
if (err != ETIMEDOUT)
err = EBUSY;
break;
case PTHREAD_EXITED: case PTHREAD_EXITED:
/* THREAD has already exited. Salvage its exit status. */ /* THREAD has already exited. Salvage its exit status. */
if (status != NULL) if (status != NULL)
@ -76,4 +90,34 @@ __pthread_join (pthread_t thread, void **status)
return err; return err;
} }
int
__pthread_join (pthread_t thread, void **status)
{
return __pthread_join_common (thread, status, 0, CLOCK_REALTIME, NULL);
}
weak_alias (__pthread_join, pthread_join); weak_alias (__pthread_join, pthread_join);
int
__pthread_tryjoin_np (pthread_t thread, void **status)
{
return __pthread_join_common (thread, status, 1, CLOCK_REALTIME, NULL);
}
weak_alias (__pthread_tryjoin_np, pthread_tryjoin_np);
int
__pthread_timedjoin_np (pthread_t thread, void **status,
const struct timespec *abstime)
{
return __pthread_join_common (thread, status, 0, CLOCK_REALTIME, abstime);
}
weak_alias (__pthread_timedjoin_np, pthread_timedjoin_np);
int
__pthread_clockjoin_np (pthread_t thread, void **status,
clockid_t clockid,
const struct timespec *abstime)
{
return __pthread_join_common (thread, status, 0, clockid, abstime);
}
weak_alias (__pthread_clockjoin_np, pthread_clockjoin_np);

View File

@ -47,6 +47,9 @@ int
__lll_abstimed_wait (void *ptr, int val, __lll_abstimed_wait (void *ptr, int val,
const struct timespec *tsp, int flags, int clk) const struct timespec *tsp, int flags, int clk)
{ {
if (clk != CLOCK_REALTIME)
return EINVAL;
int mlsec = compute_reltime (tsp, clk); int mlsec = compute_reltime (tsp, clk);
return mlsec < 0 ? KERN_TIMEDOUT : lll_timed_wait (ptr, val, mlsec, flags); return mlsec < 0 ? KERN_TIMEDOUT : lll_timed_wait (ptr, val, mlsec, flags);
} }
@ -55,6 +58,9 @@ int
__lll_abstimed_xwait (void *ptr, int lo, int hi, __lll_abstimed_xwait (void *ptr, int lo, int hi,
const struct timespec *tsp, int flags, int clk) const struct timespec *tsp, int flags, int clk)
{ {
if (clk != CLOCK_REALTIME)
return EINVAL;
int mlsec = compute_reltime (tsp, clk); int mlsec = compute_reltime (tsp, clk);
return mlsec < 0 ? KERN_TIMEDOUT : lll_timed_xwait (ptr, lo, hi, mlsec, return mlsec < 0 ? KERN_TIMEDOUT : lll_timed_xwait (ptr, lo, hi, mlsec,
flags); flags);
@ -64,6 +70,9 @@ int
__lll_abstimed_lock (void *ptr, __lll_abstimed_lock (void *ptr,
const struct timespec *tsp, int flags, int clk) const struct timespec *tsp, int flags, int clk)
{ {
if (clk != CLOCK_REALTIME)
return EINVAL;
if (lll_trylock (ptr) == 0) if (lll_trylock (ptr) == 0)
return 0; return 0;
@ -147,6 +156,9 @@ __lll_robust_abstimed_lock (void *ptr,
int wait_time = 25; int wait_time = 25;
unsigned int val; unsigned int val;
if (clk != CLOCK_REALTIME)
return EINVAL;
while (1) while (1)
{ {
val = *iptr; val = *iptr;

View File

@ -259,8 +259,8 @@ CFLAGS-tst-minstack-throw.o = -std=gnu++11
LDLIBS-tst-minstack-throw = -lstdc++ LDLIBS-tst-minstack-throw = -lstdc++
tests = tst-attr2 tst-attr3 tst-default-attr \ tests = tst-attr2 tst-attr3 tst-default-attr \
tst-mutex5 tst-mutex7 tst-mutex9 tst-mutex11 tst-mutex5a tst-mutex7a \ tst-mutex5a tst-mutex7a \
tst-mutex7robust tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 \ tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 \
tst-mutexpi5 tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a \ tst-mutexpi5 tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a \
tst-mutexpi9 \ tst-mutexpi9 \
tst-cond11 tst-cond20 tst-cond21 tst-cond22 tst-cond26 tst-cond27 \ tst-cond11 tst-cond20 tst-cond21 tst-cond22 tst-cond26 tst-cond27 \
@ -268,16 +268,13 @@ tests = tst-attr2 tst-attr3 tst-default-attr \
tst-robustpi6 tst-robustpi7 tst-robustpi9 \ tst-robustpi6 tst-robustpi7 tst-robustpi9 \
tst-rwlock2 tst-rwlock2a tst-rwlock2b tst-rwlock3 \ tst-rwlock2 tst-rwlock2a tst-rwlock2b tst-rwlock3 \
tst-rwlock6 tst-rwlock7 tst-rwlock8 \ tst-rwlock6 tst-rwlock7 tst-rwlock8 \
tst-rwlock9 tst-rwlock10 tst-rwlock11 tst-rwlock12 \ tst-rwlock9 tst-rwlock10 tst-rwlock11 \
tst-rwlock14 tst-rwlock15 tst-rwlock17 tst-rwlock18 \ tst-rwlock15 tst-rwlock17 tst-rwlock18 \
tst-once5 \ tst-once5 \
tst-sem5 tst-sem17 \ tst-sem5 tst-sem17 \
tst-align tst-align3 \ tst-align tst-align3 \
tst-kill1 tst-kill2 tst-kill3 tst-kill4 tst-kill5 tst-kill6 \ tst-kill1 tst-kill2 tst-kill3 tst-kill4 tst-kill5 tst-kill6 \
tst-raise1 \ tst-raise1 \
tst-join2 tst-join3 \
tst-join8 tst-join9 tst-join10 tst-join11 tst-join12 tst-join13 \
tst-join14 \
tst-detach1 \ tst-detach1 \
tst-eintr2 tst-eintr3 tst-eintr4 tst-eintr5 \ tst-eintr2 tst-eintr3 tst-eintr4 tst-eintr5 \
tst-tsd1 tst-tsd2 tst-tsd3 tst-tsd4 tst-tsd5 tst-tsd6 \ tst-tsd1 tst-tsd2 tst-tsd3 tst-tsd4 tst-tsd5 tst-tsd6 \
@ -301,7 +298,7 @@ tests = tst-attr2 tst-attr3 tst-default-attr \
tst-exit1 tst-exit2 tst-exit3 \ tst-exit1 tst-exit2 tst-exit3 \
tst-stdio1 tst-stdio2 \ tst-stdio1 tst-stdio2 \
tst-stack1 tst-stack2 tst-stack3 tst-stack4 \ tst-stack1 tst-stack2 tst-stack3 tst-stack4 \
tst-pthread-attr-affinity tst-pthread-mutexattr \ tst-pthread-attr-affinity \
tst-unload \ tst-unload \
tst-dlsym1 \ tst-dlsym1 \
tst-sysconf \ tst-sysconf \
@ -312,14 +309,13 @@ tests = tst-attr2 tst-attr3 tst-default-attr \
tst-context1 \ tst-context1 \
tst-sched1 \ tst-sched1 \
tst-backtrace1 \ tst-backtrace1 \
tst-abstime \
tst-vfork1 tst-vfork2 tst-vfork1x tst-vfork2x \ tst-vfork1 tst-vfork2 tst-vfork1x tst-vfork2x \
tst-getpid3 \ tst-getpid3 \
tst-setuid3 \ tst-setuid3 \
tst-initializers1 $(addprefix tst-initializers1-,\ tst-initializers1 $(addprefix tst-initializers1-,\
c89 gnu89 c99 gnu99 c11 gnu11) \ c89 gnu89 c99 gnu99 c11 gnu11) \
tst-bad-schedattr \ tst-bad-schedattr \
tst-thread_local1 tst-mutex-errorcheck \ tst-thread_local1 \
tst-robust-fork tst-create-detached tst-memstream \ tst-robust-fork tst-create-detached tst-memstream \
tst-thread-exit-clobber tst-minstack-cancel tst-minstack-exit \ tst-thread-exit-clobber tst-minstack-cancel tst-minstack-exit \
tst-minstack-throw \ tst-minstack-throw \

View File

@ -24,6 +24,7 @@
extern int __pthread_cond_timedwait_internal (pthread_cond_t *cond, extern int __pthread_cond_timedwait_internal (pthread_cond_t *cond,
pthread_mutex_t *mutex, pthread_mutex_t *mutex,
clockid_t clockid,
const struct timespec *abstime); const struct timespec *abstime);
int int
@ -31,11 +32,22 @@ __pthread_cond_timedwait (pthread_cond_t *cond,
pthread_mutex_t *mutex, pthread_mutex_t *mutex,
const struct timespec *abstime) const struct timespec *abstime)
{ {
return __pthread_cond_timedwait_internal (cond, mutex, abstime); return __pthread_cond_timedwait_internal (cond, mutex, -1, abstime);
} }
weak_alias (__pthread_cond_timedwait, pthread_cond_timedwait); weak_alias (__pthread_cond_timedwait, pthread_cond_timedwait);
int
__pthread_cond_clockwait (pthread_cond_t *cond,
pthread_mutex_t *mutex,
clockid_t clockid,
const struct timespec *abstime)
{
return __pthread_cond_timedwait_internal (cond, mutex, clockid, abstime);
}
weak_alias (__pthread_cond_clockwait, pthread_cond_clockwait);
struct cancel_ctx struct cancel_ctx
{ {
struct __pthread *wakeup; struct __pthread *wakeup;
@ -69,11 +81,17 @@ cancel_hook (void *arg)
int int
__pthread_cond_timedwait_internal (pthread_cond_t *cond, __pthread_cond_timedwait_internal (pthread_cond_t *cond,
pthread_mutex_t *mutex, pthread_mutex_t *mutex,
clockid_t clockid,
const struct timespec *abstime) const struct timespec *abstime)
{ {
error_t err; error_t err;
int cancelled, oldtype, drain; int cancelled, oldtype, drain;
clockid_t clock_id = __pthread_default_condattr.__clock; clockid_t clock_id;
if (clockid != -1)
clock_id = clockid;
else
clock_id = __pthread_default_condattr.__clock;
if (abstime && ! valid_nanoseconds (abstime->tv_nsec)) if (abstime && ! valid_nanoseconds (abstime->tv_nsec))
return EINVAL; return EINVAL;
@ -114,7 +132,7 @@ __pthread_cond_timedwait_internal (pthread_cond_t *cond,
already unblocked, progressing on the return path. */ already unblocked, progressing on the return path. */
__pthread_spin_wait (&cond->__lock); __pthread_spin_wait (&cond->__lock);
__pthread_enqueue (&cond->__queue, self); __pthread_enqueue (&cond->__queue, self);
if (cond->__attr != NULL) if (cond->__attr != NULL && clockid == -1)
clock_id = cond->__attr->__clock; clock_id = cond->__attr->__clock;
__pthread_spin_unlock (&cond->__lock); __pthread_spin_unlock (&cond->__lock);
} }

View File

@ -23,6 +23,7 @@
/* Implemented in pt-cond-timedwait.c. */ /* Implemented in pt-cond-timedwait.c. */
extern int __pthread_cond_timedwait_internal (pthread_cond_t *cond, extern int __pthread_cond_timedwait_internal (pthread_cond_t *cond,
pthread_mutex_t *mutex, pthread_mutex_t *mutex,
clockid_t clockid,
const struct timespec *abstime); const struct timespec *abstime);
@ -32,7 +33,7 @@ extern int __pthread_cond_timedwait_internal (pthread_cond_t *cond,
int int
__pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) __pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex)
{ {
return __pthread_cond_timedwait_internal (cond, mutex, 0); return __pthread_cond_timedwait_internal (cond, mutex, -1, 0);
} }
weak_alias (__pthread_cond_wait, pthread_cond_wait); weak_alias (__pthread_cond_wait, pthread_cond_wait);

View File

@ -22,6 +22,7 @@
/* Implemented in pt-rwlock-timedrdlock.c. */ /* Implemented in pt-rwlock-timedrdlock.c. */
extern int __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock extern int __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock
*rwlock, *rwlock,
clockid_t clockid,
const struct timespec const struct timespec
*abstime); *abstime);
@ -29,6 +30,6 @@ extern int __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock
int int
__pthread_rwlock_rdlock (struct __pthread_rwlock *rwlock) __pthread_rwlock_rdlock (struct __pthread_rwlock *rwlock)
{ {
return __pthread_rwlock_timedrdlock_internal (rwlock, 0); return __pthread_rwlock_timedrdlock_internal (rwlock, -1, 0);
} }
weak_alias (__pthread_rwlock_rdlock, pthread_rwlock_rdlock); weak_alias (__pthread_rwlock_rdlock, pthread_rwlock_rdlock);

View File

@ -27,6 +27,7 @@
wait forever. */ wait forever. */
int int
__pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock, __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock,
clockid_t clockid,
const struct timespec *abstime) const struct timespec *abstime)
{ {
error_t err; error_t err;
@ -62,7 +63,10 @@ __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock,
assert (rwlock->__readers == 0); assert (rwlock->__readers == 0);
if (abstime != NULL && ! valid_nanoseconds (abstime->tv_nsec)) if (abstime != NULL && ! valid_nanoseconds (abstime->tv_nsec))
return EINVAL; {
__pthread_spin_unlock (&rwlock->__lock);
return EINVAL;
}
self = _pthread_self (); self = _pthread_self ();
@ -72,7 +76,7 @@ __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock,
/* Block the thread. */ /* Block the thread. */
if (abstime != NULL) if (abstime != NULL)
err = __pthread_timedblock (self, abstime, CLOCK_REALTIME); err = __pthread_timedblock (self, abstime, clockid);
else else
{ {
err = 0; err = 0;
@ -116,6 +120,15 @@ int
__pthread_rwlock_timedrdlock (struct __pthread_rwlock *rwlock, __pthread_rwlock_timedrdlock (struct __pthread_rwlock *rwlock,
const struct timespec *abstime) const struct timespec *abstime)
{ {
return __pthread_rwlock_timedrdlock_internal (rwlock, abstime); return __pthread_rwlock_timedrdlock_internal (rwlock, CLOCK_REALTIME, abstime);
} }
weak_alias (__pthread_rwlock_timedrdlock, pthread_rwlock_timedrdlock) weak_alias (__pthread_rwlock_timedrdlock, pthread_rwlock_timedrdlock)
int
__pthread_rwlock_clockrdlock (struct __pthread_rwlock *rwlock,
clockid_t clockid,
const struct timespec *abstime)
{
return __pthread_rwlock_timedrdlock_internal (rwlock, clockid, abstime);
}
weak_alias (__pthread_rwlock_clockrdlock, pthread_rwlock_clockrdlock)

View File

@ -27,6 +27,7 @@
shall not time out. */ shall not time out. */
int int
__pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock *rwlock, __pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock *rwlock,
clockid_t clockid,
const struct timespec *abstime) const struct timespec *abstime)
{ {
error_t err; error_t err;
@ -48,7 +49,10 @@ __pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock *rwlock,
/* The lock is busy. */ /* The lock is busy. */
if (abstime != NULL && ! valid_nanoseconds (abstime->tv_nsec)) if (abstime != NULL && ! valid_nanoseconds (abstime->tv_nsec))
return EINVAL; {
__pthread_spin_unlock (&rwlock->__lock);
return EINVAL;
}
self = _pthread_self (); self = _pthread_self ();
@ -58,7 +62,7 @@ __pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock *rwlock,
/* Block the thread. */ /* Block the thread. */
if (abstime != NULL) if (abstime != NULL)
err = __pthread_timedblock (self, abstime, CLOCK_REALTIME); err = __pthread_timedblock (self, abstime, clockid);
else else
{ {
err = 0; err = 0;
@ -99,6 +103,15 @@ int
__pthread_rwlock_timedwrlock (struct __pthread_rwlock *rwlock, __pthread_rwlock_timedwrlock (struct __pthread_rwlock *rwlock,
const struct timespec *abstime) const struct timespec *abstime)
{ {
return __pthread_rwlock_timedwrlock_internal (rwlock, abstime); return __pthread_rwlock_timedwrlock_internal (rwlock, CLOCK_REALTIME, abstime);
} }
weak_alias (__pthread_rwlock_timedwrlock, pthread_rwlock_timedwrlock) weak_alias (__pthread_rwlock_timedwrlock, pthread_rwlock_timedwrlock)
int
__pthread_rwlock_clockwrlock (struct __pthread_rwlock *rwlock,
clockid_t clockid,
const struct timespec *abstime)
{
return __pthread_rwlock_timedwrlock_internal (rwlock, clockid, abstime);
}
weak_alias (__pthread_rwlock_clockwrlock, pthread_rwlock_clockwrlock)

View File

@ -24,6 +24,7 @@
/* Implemented in pt-rwlock-timedwrlock.c. */ /* Implemented in pt-rwlock-timedwrlock.c. */
extern int __pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock extern int __pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock
*rwlock, *rwlock,
clockid_t clockid,
const struct timespec const struct timespec
*abstime); *abstime);
@ -31,6 +32,6 @@ extern int __pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock
int int
__pthread_rwlock_wrlock (struct __pthread_rwlock *rwlock) __pthread_rwlock_wrlock (struct __pthread_rwlock *rwlock)
{ {
return __pthread_rwlock_timedwrlock_internal (rwlock, 0); return __pthread_rwlock_timedwrlock_internal (rwlock, -1, 0);
} }
weak_alias (__pthread_rwlock_wrlock, pthread_rwlock_wrlock); weak_alias (__pthread_rwlock_wrlock, pthread_rwlock_wrlock);

View File

@ -222,6 +222,32 @@ extern void pthread_exit (void *__status) __attribute__ ((__noreturn__));
the exit status of the thread in *STATUS. */ the exit status of the thread in *STATUS. */
extern int pthread_join (pthread_t __threadp, void **__status); extern int pthread_join (pthread_t __threadp, void **__status);
#ifdef __USE_GNU
/* Check whether thread TH has terminated. If yes return the status of
the thread in *THREAD_RETURN, if THREAD_RETURN is not NULL. */
extern int pthread_tryjoin_np (pthread_t __th, void **__thread_return) __THROW;
/* Make calling thread wait for termination of the thread TH, but only
until TIMEOUT. The exit status of the thread is stored in
*THREAD_RETURN, if THREAD_RETURN is not NULL.
This function is a cancellation point and therefore not marked with
__THROW. */
extern int pthread_timedjoin_np (pthread_t __th, void **__thread_return,
const struct timespec *__abstime);
/* Make calling thread wait for termination of the thread TH, but only
until TIMEOUT measured against the clock specified by CLOCKID. The
exit status of the thread is stored in *THREAD_RETURN, if
THREAD_RETURN is not NULL.
This function is a cancellation point and therefore not marked with
__THROW. */
extern int pthread_clockjoin_np (pthread_t __th, void **__thread_return,
clockid_t __clockid,
const struct timespec *__abstime);
#endif
/* Indicate that the storage for THREAD can be reclaimed when it /* Indicate that the storage for THREAD can be reclaimed when it
terminates. */ terminates. */
extern int pthread_detach (pthread_t __threadp); extern int pthread_detach (pthread_t __threadp);
@ -401,6 +427,13 @@ extern int pthread_mutex_timedlock (struct __pthread_mutex *__restrict __mutex,
__THROWNL __nonnull ((1, 2)); __THROWNL __nonnull ((1, 2));
#endif #endif
#ifdef __USE_GNU
extern int pthread_mutex_clocklock (pthread_mutex_t *__restrict __mutex,
clockid_t __clockid,
const struct timespec *__restrict
__abstime) __THROWNL __nonnull ((1, 3));
#endif
/* Unlock MUTEX. */ /* Unlock MUTEX. */
extern int pthread_mutex_unlock (pthread_mutex_t *__mutex) extern int pthread_mutex_unlock (pthread_mutex_t *__mutex)
__THROWNL __nonnull ((1)); __THROWNL __nonnull ((1));
@ -517,6 +550,21 @@ extern int pthread_cond_timedwait (pthread_cond_t *__restrict __cond,
pthread_mutex_t *__restrict __mutex, pthread_mutex_t *__restrict __mutex,
__const struct timespec *__restrict __abstime) __const struct timespec *__restrict __abstime)
__nonnull ((1, 2, 3)); __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
/* Spin locks. */ /* Spin locks. */
@ -623,6 +671,13 @@ extern int pthread_rwlock_timedrdlock (struct __pthread_rwlock *__restrict __rwl
__THROWNL __nonnull ((1, 2)); __THROWNL __nonnull ((1, 2));
# endif # endif
# ifdef __USE_GNU
extern int pthread_rwlock_clockrdlock (pthread_rwlock_t *__restrict __rwlock,
clockid_t __clockid,
const struct timespec *__restrict
__abstime) __THROWNL __nonnull ((1, 3));
# endif
/* Acquire the rwlock *RWLOCK for writing. */ /* Acquire the rwlock *RWLOCK for writing. */
extern int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock) extern int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock)
__THROWNL __nonnull ((1)); __THROWNL __nonnull ((1));
@ -639,6 +694,13 @@ extern int pthread_rwlock_timedwrlock (struct __pthread_rwlock *__restrict __rwl
__THROWNL __nonnull ((1, 2)); __THROWNL __nonnull ((1, 2));
# endif # endif
# ifdef __USE_GNU
extern int pthread_rwlock_clockwrlock (pthread_rwlock_t *__restrict __rwlock,
clockid_t __clockid,
const struct timespec *__restrict
__abstime) __THROWNL __nonnull ((1, 3));
# endif
/* Release the lock held by the current thread on *RWLOCK. */ /* Release the lock held by the current thread on *RWLOCK. */
extern int pthread_rwlock_unlock (pthread_rwlock_t *__rwlock) extern int pthread_rwlock_unlock (pthread_rwlock_t *__rwlock)
__THROWNL __nonnull ((1)); __THROWNL __nonnull ((1));

View File

@ -50,6 +50,11 @@ extern int __pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex);
extern int __pthread_cond_timedwait (pthread_cond_t *cond, extern int __pthread_cond_timedwait (pthread_cond_t *cond,
pthread_mutex_t *mutex, pthread_mutex_t *mutex,
const struct timespec *abstime); 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_cond_destroy (pthread_cond_t *cond); extern int __pthread_cond_destroy (pthread_cond_t *cond);
typedef struct __cthread *__cthread_t; typedef struct __cthread *__cthread_t;

View File

@ -24,7 +24,9 @@
#include <hurdlock.h> #include <hurdlock.h>
int int
__pthread_mutex_timedlock (pthread_mutex_t *mtxp, const struct timespec *tsp) __pthread_mutex_clocklock (pthread_mutex_t *mtxp,
clockid_t clockid,
const struct timespec *tsp)
{ {
struct __pthread *self; struct __pthread *self;
int ret, flags = mtxp->__flags & GSYNC_SHARED; int ret, flags = mtxp->__flags & GSYNC_SHARED;
@ -32,7 +34,7 @@ __pthread_mutex_timedlock (pthread_mutex_t *mtxp, const struct timespec *tsp)
switch (MTX_TYPE (mtxp)) switch (MTX_TYPE (mtxp))
{ {
case PT_MTX_NORMAL: case PT_MTX_NORMAL:
ret = lll_abstimed_lock (&mtxp->__lock, tsp, flags); ret = lll_abstimed_lock (&mtxp->__lock, tsp, flags, clockid);
break; break;
case PT_MTX_RECURSIVE: case PT_MTX_RECURSIVE:
@ -45,7 +47,7 @@ __pthread_mutex_timedlock (pthread_mutex_t *mtxp, const struct timespec *tsp)
++mtxp->__cnt; ++mtxp->__cnt;
ret = 0; ret = 0;
} }
else if ((ret = lll_abstimed_lock (&mtxp->__lock, tsp, flags)) == 0) else if ((ret = lll_abstimed_lock (&mtxp->__lock, tsp, flags, clockid)) == 0)
{ {
mtx_set_owner (mtxp, self, flags); mtx_set_owner (mtxp, self, flags);
mtxp->__cnt = 1; mtxp->__cnt = 1;
@ -57,7 +59,7 @@ __pthread_mutex_timedlock (pthread_mutex_t *mtxp, const struct timespec *tsp)
self = _pthread_self (); self = _pthread_self ();
if (mtx_owned_p (mtxp, self, flags)) if (mtx_owned_p (mtxp, self, flags))
ret = EDEADLK; ret = EDEADLK;
else if ((ret = lll_abstimed_lock (&mtxp->__lock, tsp, flags)) == 0) else if ((ret = lll_abstimed_lock (&mtxp->__lock, tsp, flags, clockid)) == 0)
mtx_set_owner (mtxp, self, flags); mtx_set_owner (mtxp, self, flags);
break; break;
@ -66,7 +68,7 @@ __pthread_mutex_timedlock (pthread_mutex_t *mtxp, const struct timespec *tsp)
case PT_MTX_RECURSIVE | PTHREAD_MUTEX_ROBUST: case PT_MTX_RECURSIVE | PTHREAD_MUTEX_ROBUST:
case PT_MTX_ERRORCHECK | PTHREAD_MUTEX_ROBUST: case PT_MTX_ERRORCHECK | PTHREAD_MUTEX_ROBUST:
self = _pthread_self (); self = _pthread_self ();
ROBUST_LOCK (self, mtxp, lll_robust_abstimed_lock, tsp, flags); ROBUST_LOCK (self, mtxp, lll_robust_abstimed_lock, tsp, flags, clockid);
break; break;
default: default:
@ -76,5 +78,13 @@ __pthread_mutex_timedlock (pthread_mutex_t *mtxp, const struct timespec *tsp)
return ret; return ret;
} }
weak_alias (__pthread_mutex_clocklock, pthread_mutex_clocklock)
int
__pthread_mutex_timedlock (pthread_mutex_t *mutex,
const struct timespec *tsp)
{
return __pthread_mutex_clocklock (mutex, CLOCK_REALTIME, tsp);
}
weak_alias (__pthread_mutex_timedlock, pthread_mutex_timedlock) weak_alias (__pthread_mutex_timedlock, pthread_mutex_timedlock)
hidden_def (__pthread_mutex_timedlock) hidden_def (__pthread_mutex_timedlock)

View File

@ -155,12 +155,19 @@ GLIBC_2.32 mtx_lock F
GLIBC_2.32 mtx_timedlock F GLIBC_2.32 mtx_timedlock F
GLIBC_2.32 mtx_trylock F GLIBC_2.32 mtx_trylock F
GLIBC_2.32 mtx_unlock F GLIBC_2.32 mtx_unlock F
GLIBC_2.32 pthread_clockjoin_np F
GLIBC_2.32 pthread_cond_clockwait F
GLIBC_2.32 pthread_mutex_clocklock F
GLIBC_2.32 pthread_mutex_consistent F GLIBC_2.32 pthread_mutex_consistent F
GLIBC_2.32 pthread_mutex_consistent_np F GLIBC_2.32 pthread_mutex_consistent_np F
GLIBC_2.32 pthread_mutexattr_getrobust F GLIBC_2.32 pthread_mutexattr_getrobust F
GLIBC_2.32 pthread_mutexattr_getrobust_np F GLIBC_2.32 pthread_mutexattr_getrobust_np F
GLIBC_2.32 pthread_mutexattr_setrobust F GLIBC_2.32 pthread_mutexattr_setrobust F
GLIBC_2.32 pthread_mutexattr_setrobust_np F GLIBC_2.32 pthread_mutexattr_setrobust_np F
GLIBC_2.32 pthread_rwlock_clockrdlock F
GLIBC_2.32 pthread_rwlock_clockwrlock F
GLIBC_2.32 pthread_timedjoin_np F
GLIBC_2.32 pthread_tryjoin_np F
GLIBC_2.32 thrd_create F GLIBC_2.32 thrd_create F
GLIBC_2.32 thrd_detach F GLIBC_2.32 thrd_detach F
GLIBC_2.32 thrd_exit F GLIBC_2.32 thrd_exit F

View File

@ -51,17 +51,23 @@ tests += tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \
tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \ tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
tst-cond23 tst-cond24 tst-cond25 \ tst-cond23 tst-cond24 tst-cond25 \
tst-cond-except \ tst-cond-except \
tst-join1 tst-join4 tst-join5 tst-join6 tst-join7 \ tst-join1 tst-join2 tst-join3 tst-join4 tst-join5 tst-join6 tst-join7 \
tst-join8 tst-join9 tst-join10 tst-join11 tst-join12 tst-join13 \
tst-join14 \
tst-key1 tst-key2 tst-key3 tst-key4 \ tst-key1 tst-key2 tst-key3 tst-key4 \
tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex6 tst-mutex10 \ tst-mutex-errorcheck tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 \
tst-mutex5 tst-mutex6 tst-mutex7 tst-mutex7robust tst-mutex9 \
tst-mutex10 tst-mutex11 tst-pthread-mutexattr \
tst-once1 tst-once2 tst-once3 tst-once4 \ tst-once1 tst-once2 tst-once3 tst-once4 \
tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \ tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \
tst-robust6 tst-robust7 tst-robust9 tst-robust10 \ tst-robust6 tst-robust7 tst-robust9 tst-robust10 \
tst-rwlock1 tst-rwlock4 tst-rwlock5 tst-rwlock13 tst-rwlock16 \ tst-rwlock1 tst-rwlock4 tst-rwlock5 tst-rwlock12 \
tst-rwlock13 tst-rwlock14 tst-rwlock16 \
tst-rwlock-tryrdlock-stall tst-rwlock-trywrlock-stall \ tst-rwlock-tryrdlock-stall tst-rwlock-trywrlock-stall \
tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem6 tst-sem7 \ tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem6 tst-sem7 \
tst-sem8 tst-sem9 tst-sem10 tst-sem14 tst-sem15 tst-sem16 \ tst-sem8 tst-sem9 tst-sem10 tst-sem14 tst-sem15 tst-sem16 \
tst-spin1 tst-spin2 tst-spin3 tst-spin4 tst-spin1 tst-spin2 tst-spin3 tst-spin4 \
tst-abstime
tests-internal += tst-robust8 tests-internal += tst-robust8