summaryrefslogtreecommitdiff
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
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.
-rw-r--r--libpthread/linuxthreads/condvar.c48
-rw-r--r--libpthread/linuxthreads/internals.h19
-rw-r--r--libpthread/linuxthreads/sysdeps/pthread/bits/pthreadtypes.h9
-rw-r--r--libpthread/linuxthreads/sysdeps/pthread/pthread.h12
4 files changed, 85 insertions, 3 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;
+}
diff --git a/libpthread/linuxthreads/internals.h b/libpthread/linuxthreads/internals.h
index ab6b01528..720be8ec0 100644
--- a/libpthread/linuxthreads/internals.h
+++ b/libpthread/linuxthreads/internals.h
@@ -51,6 +51,25 @@
# define THREAD_SETMEM_NC(descr, member, value) descr->member = (value)
#endif
+/* Conditional variable attribute data structure. */
+struct pthread_condattr
+{
+ /* Combination of values:
+
+ Bit 0 : flag whether coditional variable will be shareable between
+ processes.
+
+ Bit 1-7: clock ID. */
+ int value;
+};
+
+/* The __NWAITERS field is used as a counter and to house the number
+ of bits for other purposes. COND_CLOCK_BITS is the number
+ of bits needed to represent the ID of the clock. COND_NWAITERS_SHIFT
+ is the number of bits reserved for other purposes like the clock. */
+#define COND_CLOCK_BITS 1
+#define COND_NWAITERS_SHIFT 1
+
/* Arguments passed to thread creation routine */
struct pthread_start_args {
diff --git a/libpthread/linuxthreads/sysdeps/pthread/bits/pthreadtypes.h b/libpthread/linuxthreads/sysdeps/pthread/bits/pthreadtypes.h
index 3eb592919..638dc75c9 100644
--- a/libpthread/linuxthreads/sysdeps/pthread/bits/pthreadtypes.h
+++ b/libpthread/linuxthreads/sysdeps/pthread/bits/pthreadtypes.h
@@ -25,6 +25,8 @@
#define __need_schedparam
#include <bits/sched.h>
+#define __SIZEOF_PTHREAD_CONDATTR_T 4
+
/* Fast locks (not abstract because mutexes and conditions aren't abstract). */
struct _pthread_fastlock
{
@@ -63,12 +65,13 @@ typedef struct
} pthread_cond_t;
-/* Attribute for conditionally variables. */
-typedef struct
+typedef union
{
- int __dummy;
+ char __size[__SIZEOF_PTHREAD_CONDATTR_T];
+ int __align;
} pthread_condattr_t;
+
/* Keys for thread-specific data */
typedef unsigned int pthread_key_t;
diff --git a/libpthread/linuxthreads/sysdeps/pthread/pthread.h b/libpthread/linuxthreads/sysdeps/pthread/pthread.h
index 0d175025b..9bcd887ed 100644
--- a/libpthread/linuxthreads/sysdeps/pthread/pthread.h
+++ b/libpthread/linuxthreads/sysdeps/pthread/pthread.h
@@ -455,6 +455,18 @@ extern int pthread_condattr_getpshared (const pthread_condattr_t *
extern int pthread_condattr_setpshared (pthread_condattr_t *__attr,
int __pshared) __THROW;
+#ifdef __USE_XOPEN2K
+/* Get the clock selected for the condition variable attribute ATTR. */
+extern int pthread_condattr_getclock (const pthread_condattr_t *
+ __restrict __attr,
+ __clockid_t *__restrict __clock_id)
+ __THROW __nonnull ((1, 2));
+
+/* Set the clock selected for the condition variable attribute ATTR. */
+extern int pthread_condattr_setclock (pthread_condattr_t *__attr,
+ __clockid_t __clock_id)
+ __THROW __nonnull ((1));
+#endif
#if defined __USE_UNIX98 || defined __USE_XOPEN2K
/* Functions for handling read-write locks. */