summaryrefslogtreecommitdiff
path: root/libpthread/linuxthreads/condvar.c
diff options
context:
space:
mode:
authorWaldemar Brodkorb <wbx@uclibc-ng.org>2018-04-22 18:59:13 +0100
committerWaldemar Brodkorb <wbx@uclibc-ng.org>2018-04-22 19:01:57 +0100
commit04a676f3c8d2443499f27612f69ee88e12089e61 (patch)
treea6dac60812a5c5c748aa67330b81a36d667f3b9d /libpthread/linuxthreads/condvar.c
parentd86bd35298834f3162459dde763f7976f5c2a523 (diff)
linuxthreads: implement pthread_condattr_{s,g}etclock()
More applications are using pthread_condattr_setclock()/ pthread_condattr_getclock() in their code. Port these two functions from NPTL over to be more compatible.
Diffstat (limited to 'libpthread/linuxthreads/condvar.c')
-rw-r--r--libpthread/linuxthreads/condvar.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/libpthread/linuxthreads/condvar.c b/libpthread/linuxthreads/condvar.c
index 35daacf15..6ac1622da 100644
--- a/libpthread/linuxthreads/condvar.c
+++ b/libpthread/linuxthreads/condvar.c
@@ -275,6 +275,7 @@ libpthread_hidden_def(pthread_cond_broadcast)
int pthread_condattr_init(pthread_condattr_t *attr attribute_unused)
{
+ memset (attr, '\0', sizeof (*attr));
return 0;
}
libpthread_hidden_def(pthread_condattr_init)
@@ -302,3 +303,50 @@ int pthread_condattr_setpshared (pthread_condattr_t *attr attribute_unused, int
return 0;
}
+
+int pthread_condattr_getclock (const pthread_condattr_t *attr, clockid_t *clock_id)
+{
+ *clock_id = (((((const struct pthread_condattr *) attr)->value) >> 1)
+ & ((1 << COND_NWAITERS_SHIFT) - 1));
+ return 0;
+}
+
+int pthread_condattr_setclock (pthread_condattr_t *attr, clockid_t clock_id)
+{
+ /* Only a few clocks are allowed. CLOCK_REALTIME is always allowed.
+ CLOCK_MONOTONIC only if the kernel has the necessary support. */
+ if (clock_id == CLOCK_MONOTONIC)
+ {
+#ifndef __ASSUME_POSIX_TIMERS
+# ifdef __NR_clock_getres
+ /* Check whether the clock is available. */
+ static int avail;
+
+ if (avail == 0)
+ {
+ struct timespec ts;
+
+ INTERNAL_SYSCALL_DECL (err);
+ int val;
+ val = INTERNAL_SYSCALL (clock_getres, err, 2, CLOCK_MONOTONIC, &ts);
+ avail = INTERNAL_SYSCALL_ERROR_P (val, err) ? -1 : 1;
+ }
+
+ if (avail < 0)
+# endif
+ /* Not available. */
+ return EINVAL;
+#endif
+ }
+ else if (clock_id != CLOCK_REALTIME)
+ /* If more clocks are allowed some day the storing of the clock ID
+ in the pthread_cond_t structure needs to be adjusted. */
+ return EINVAL;
+
+ int *valuep = &((struct pthread_condattr *) attr)->value;
+
+ *valuep = ((*valuep & ~(((1 << COND_NWAITERS_SHIFT) - 1) << 1))
+ | (clock_id << 1));
+
+ return 0;
+}