Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 7e958d0

Browse files
Tom CherryGerrit Code Review
authored andcommitted
Merge "Implement new clock wait functions"
2 parents c80af7f + 6901080 commit 7e958d0

File tree

9 files changed

+351
-32
lines changed

9 files changed

+351
-32
lines changed

libc/bionic/pthread_cond.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,18 @@ extern "C" int pthread_cond_timedwait_monotonic_np(pthread_cond_t* cond_interfac
215215
return __pthread_cond_timedwait(__get_internal_cond(cond_interface), mutex, false, abs_timeout);
216216
}
217217

218+
int pthread_cond_clockwait(pthread_cond_t* cond_interface, pthread_mutex_t* mutex, clockid_t clock,
219+
const struct timespec* abs_timeout) {
220+
switch (clock) {
221+
case CLOCK_MONOTONIC:
222+
return pthread_cond_timedwait_monotonic_np(cond_interface, mutex, abs_timeout);
223+
case CLOCK_REALTIME:
224+
return pthread_cond_timedwait(cond_interface, mutex, abs_timeout);
225+
default:
226+
return EINVAL;
227+
}
228+
}
229+
218230
#if !defined(__LP64__)
219231
// TODO: this exists only for backward binary compatibility on 32 bit platforms.
220232
extern "C" int pthread_cond_timedwait_monotonic(pthread_cond_t* cond_interface,

libc/bionic/pthread_mutex.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -989,6 +989,24 @@ int pthread_mutex_timedlock_monotonic_np(pthread_mutex_t* mutex_interface,
989989
return __pthread_mutex_timedlock(mutex_interface, false, abs_timeout, __FUNCTION__);
990990
}
991991

992+
int pthread_mutex_clocklock(pthread_mutex_t* mutex_interface, clockid_t clock,
993+
const struct timespec* abs_timeout) {
994+
switch (clock) {
995+
case CLOCK_MONOTONIC:
996+
return __pthread_mutex_timedlock(mutex_interface, false, abs_timeout, __FUNCTION__);
997+
case CLOCK_REALTIME:
998+
return __pthread_mutex_timedlock(mutex_interface, true, abs_timeout, __FUNCTION__);
999+
default: {
1000+
pthread_mutex_internal_t* mutex = __get_internal_mutex(mutex_interface);
1001+
uint16_t old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed);
1002+
if (IsMutexDestroyed(old_state)) {
1003+
return HandleUsingDestroyedMutex(mutex_interface, __FUNCTION__);
1004+
}
1005+
return EINVAL;
1006+
}
1007+
}
1008+
}
1009+
9921010
int pthread_mutex_destroy(pthread_mutex_t* mutex_interface) {
9931011
pthread_mutex_internal_t* mutex = __get_internal_mutex(mutex_interface);
9941012
uint16_t old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed);

libc/bionic/pthread_rwlock.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,18 @@ int pthread_rwlock_timedrdlock_monotonic_np(pthread_rwlock_t* rwlock_interface,
429429
return __pthread_rwlock_timedrdlock(rwlock, false, abs_timeout);
430430
}
431431

432+
int pthread_rwlock_clockrdlock(pthread_rwlock_t* rwlock_interface, clockid_t clock,
433+
const struct timespec* abs_timeout) {
434+
switch (clock) {
435+
case CLOCK_MONOTONIC:
436+
return pthread_rwlock_timedrdlock_monotonic_np(rwlock_interface, abs_timeout);
437+
case CLOCK_REALTIME:
438+
return pthread_rwlock_timedrdlock(rwlock_interface, abs_timeout);
439+
default:
440+
return EINVAL;
441+
}
442+
}
443+
432444
int pthread_rwlock_tryrdlock(pthread_rwlock_t* rwlock_interface) {
433445
return __pthread_rwlock_tryrdlock(__get_internal_rwlock(rwlock_interface));
434446
}
@@ -455,6 +467,18 @@ int pthread_rwlock_timedwrlock_monotonic_np(pthread_rwlock_t* rwlock_interface,
455467
return __pthread_rwlock_timedwrlock(rwlock, false, abs_timeout);
456468
}
457469

470+
int pthread_rwlock_clockwrlock(pthread_rwlock_t* rwlock_interface, clockid_t clock,
471+
const struct timespec* abs_timeout) {
472+
switch (clock) {
473+
case CLOCK_MONOTONIC:
474+
return pthread_rwlock_timedwrlock_monotonic_np(rwlock_interface, abs_timeout);
475+
case CLOCK_REALTIME:
476+
return pthread_rwlock_timedwrlock(rwlock_interface, abs_timeout);
477+
default:
478+
return EINVAL;
479+
}
480+
}
481+
458482
int pthread_rwlock_trywrlock(pthread_rwlock_t* rwlock_interface) {
459483
return __pthread_rwlock_trywrlock(__get_internal_rwlock(rwlock_interface));
460484
}

libc/bionic/semaphore.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,17 @@ int sem_timedwait_monotonic_np(sem_t* sem, const timespec* abs_timeout) {
275275
return __sem_timedwait(sem, abs_timeout, false);
276276
}
277277

278+
int sem_clockwait(sem_t* sem, clockid_t clock, const timespec* abs_timeout) {
279+
switch (clock) {
280+
case CLOCK_MONOTONIC:
281+
return sem_timedwait_monotonic_np(sem, abs_timeout);
282+
case CLOCK_REALTIME:
283+
return sem_timedwait(sem, abs_timeout);
284+
default:
285+
return EINVAL;
286+
}
287+
}
288+
278289
int sem_post(sem_t* sem) {
279290
atomic_uint* sem_count_ptr = SEM_TO_ATOMIC_POINTER(sem);
280291
unsigned int shared = SEM_GET_SHARED(sem_count_ptr);

libc/include/pthread.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ int pthread_condattr_setclock(pthread_condattr_t* __attr, clockid_t __clock) __I
121121
int pthread_condattr_setpshared(pthread_condattr_t* __attr, int __shared);
122122

123123
int pthread_cond_broadcast(pthread_cond_t* __cond);
124+
int pthread_cond_clockwait(pthread_cond_t* __cond, pthread_mutex_t* __mutex, clockid_t __clock,
125+
const struct timespec* __timeout) __INTRODUCED_IN(30);
124126
int pthread_cond_destroy(pthread_cond_t* __cond);
125127
int pthread_cond_init(pthread_cond_t* __cond, const pthread_condattr_t* __attr);
126128
int pthread_cond_signal(pthread_cond_t* __cond);
@@ -130,8 +132,10 @@ int pthread_cond_timedwait(pthread_cond_t* __cond, pthread_mutex_t* __mutex, con
130132
* typically inappropriate, since that clock can change dramatically, causing the timeout to
131133
* either expire earlier or much later than intended.
132134
* Condition variables have an initialization option to use CLOCK_MONOTONIC, and in addition,
133-
* Android provides this API to use CLOCK_MONOTONIC on a condition variable for this single wait
134-
* no matter how it was initialized.
135+
* Android provides pthread_cond_timedwait_monotonic_np to use CLOCK_MONOTONIC on a condition
136+
* variable for this single wait no matter how it was initialized.
137+
* Note that pthread_cond_clockwait() allows specifying an arbitrary clock and has superseded this
138+
* function.
135139
*/
136140
int pthread_cond_timedwait_monotonic_np(pthread_cond_t* __cond, pthread_mutex_t* __mutex,
137141
const struct timespec* __timeout) __INTRODUCED_IN_64(28);
@@ -181,18 +185,22 @@ int pthread_mutexattr_setpshared(pthread_mutexattr_t* __attr, int __shared);
181185
int pthread_mutexattr_settype(pthread_mutexattr_t* __attr, int __type);
182186
int pthread_mutexattr_setprotocol(pthread_mutexattr_t* __attr, int __protocol) __INTRODUCED_IN(28);
183187

188+
int pthread_mutex_clocklock(pthread_mutex_t* __mutex, clockid_t __clock,
189+
const struct timespec* __abstime) __INTRODUCED_IN(30);
184190
int pthread_mutex_destroy(pthread_mutex_t* __mutex);
185191
int pthread_mutex_init(pthread_mutex_t* __mutex, const pthread_mutexattr_t* __attr);
186192
int pthread_mutex_lock(pthread_mutex_t* __mutex);
187193
int pthread_mutex_timedlock(pthread_mutex_t* __mutex, const struct timespec* __timeout)
188194
__INTRODUCED_IN(21);
189195

190196
/*
191-
* POSIX only supports using pthread_mutex_timedlock() with CLOCK_REALTIME, however that is
192-
* typically inappropriate, since that clock can change dramatically, causing the timeout to
197+
* POSIX historically only supported using pthread_mutex_timedlock() with CLOCK_REALTIME, however
198+
* that is typically inappropriate, since that clock can change dramatically, causing the timeout to
193199
* either expire earlier or much later than intended.
194200
* This function is added to use a timespec based on CLOCK_MONOTONIC that does not suffer
195201
* from this issue.
202+
* Note that pthread_mutex_clocklock() allows specifying an arbitrary clock and has superseded this
203+
* function.
196204
*/
197205
int pthread_mutex_timedlock_monotonic_np(pthread_mutex_t* __mutex, const struct timespec* __timeout)
198206
__INTRODUCED_IN(28);
@@ -226,6 +234,10 @@ int pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t* __attr, int* __kin
226234
__INTRODUCED_IN(23);
227235
int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t* __attr, int __kind) __INTRODUCED_IN(23);
228236

237+
int pthread_rwlock_clockrdlock(pthread_rwlock_t* __rwlock, clockid_t __clock,
238+
const struct timespec* __timeout) __INTRODUCED_IN(30);
239+
int pthread_rwlock_clockwrlock(pthread_rwlock_t* __rwlock, clockid_t __clock,
240+
const struct timespec* __timeout) __INTRODUCED_IN(30);
229241
int pthread_rwlock_destroy(pthread_rwlock_t* __rwlock);
230242
int pthread_rwlock_init(pthread_rwlock_t* __rwlock, const pthread_rwlockattr_t* __attr);
231243
int pthread_rwlock_rdlock(pthread_rwlock_t* __rwlock);

libc/include/semaphore.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#define _SEMAPHORE_H
3131

3232
#include <sys/cdefs.h>
33+
#include <sys/types.h>
3334

3435
__BEGIN_DECLS
3536

@@ -44,16 +45,19 @@ typedef struct {
4445

4546
#define SEM_FAILED __BIONIC_CAST(reinterpret_cast, sem_t*, 0)
4647

48+
int sem_clockwait(sem_t* __sem, clockid_t __clock, const struct timespec* __ts) __INTRODUCED_IN(30);
4749
int sem_destroy(sem_t* __sem);
4850
int sem_getvalue(sem_t* __sem, int* __value);
4951
int sem_init(sem_t* __sem, int __shared, unsigned int __value);
5052
int sem_post(sem_t* __sem);
5153
int sem_timedwait(sem_t* __sem, const struct timespec* __ts);
5254
/*
53-
* POSIX only supports using sem_timedwait() with CLOCK_REALTIME, however that is typically
54-
* inappropriate, since that clock can change dramatically, causing the timeout to either
55+
* POSIX historically only supported using sem_timedwait() with CLOCK_REALTIME, however that is
56+
* typically inappropriate, since that clock can change dramatically, causing the timeout to either
5557
* expire earlier or much later than intended. This function is added to use a timespec based
5658
* on CLOCK_MONOTONIC that does not suffer from this issue.
59+
* Note that sem_clockwait() allows specifying an arbitrary clock and has superseded this
60+
* function.
5761
*/
5862
int sem_timedwait_monotonic_np(sem_t* __sem, const struct timespec* __ts) __INTRODUCED_IN(28);
5963
int sem_trywait(sem_t* __sem);

libc/libc.map.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,6 +1498,11 @@ LIBC_R { # introduced=R
14981498
mtx_timedlock;
14991499
mtx_trylock;
15001500
mtx_unlock;
1501+
pthread_cond_clockwait;
1502+
pthread_mutex_clocklock;
1503+
pthread_rwlock_clockrdlock;
1504+
pthread_rwlock_clockwrlock;
1505+
sem_clockwait;
15011506
thrd_create;
15021507
thrd_current;
15031508
thrd_detach;

0 commit comments

Comments
 (0)