summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps/linux')
-rw-r--r--libc/sysdeps/linux/common/bits/uClibc_mutex.h22
-rw-r--r--libc/sysdeps/linux/common/bits/uClibc_pthread.h7
2 files changed, 21 insertions, 8 deletions
diff --git a/libc/sysdeps/linux/common/bits/uClibc_mutex.h b/libc/sysdeps/linux/common/bits/uClibc_mutex.h
index c6094c3d2..02bcc7225 100644
--- a/libc/sysdeps/linux/common/bits/uClibc_mutex.h
+++ b/libc/sysdeps/linux/common/bits/uClibc_mutex.h
@@ -13,8 +13,16 @@
#ifdef __UCLIBC_HAS_THREADS__
#include <pthread.h>
+#include <bits/libc-lock.h>
#include <bits/uClibc_pthread.h>
+#define __uclibc_maybe_call(FUNC, ARGS) \
+ (__extension__ ({ \
+ __typeof (FUNC) *_fn = (FUNC); \
+ if (_fn != NULL) { (*_fn) ARGS; } \
+ }))
+
+
#define __UCLIBC_MUTEX_TYPE pthread_mutex_t
#define __UCLIBC_MUTEX(M) pthread_mutex_t M
@@ -22,19 +30,23 @@
#define __UCLIBC_MUTEX_STATIC(M,I) static pthread_mutex_t M = I
#define __UCLIBC_MUTEX_EXTERN(M) extern pthread_mutex_t M
+#define __UCLIBC_MUTEX_INIT_VAR(M) \
+ __uclibc_maybe_call(__pthread_mutex_init,(&(M),NULL))
+
#define __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(M) \
- __pthread_mutex_lock(&(M))
+ __uclibc_maybe_call(__pthread_mutex_lock,(&(M)))
#define __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(M) \
- __pthread_mutex_unlock(&(M))
+ __uclibc_maybe_call(__pthread_mutex_unlock,(&(M)))
#define __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE(M) \
- __pthread_mutex_trylock(&(M))
+ __uclibc_maybe_call(__pthread_mutex_trylock,(&(M)))
#define __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,C) \
do { \
struct _pthread_cleanup_buffer __infunc_pthread_cleanup_buffer; \
- if (C) { \
+ int __infunc_need_locking = ((C) && (__pthread_mutex_lock != NULL)); \
+ if (__infunc_need_locking) { \
_pthread_cleanup_push_defer(&__infunc_pthread_cleanup_buffer, \
(void (*) (void *))__pthread_mutex_unlock, \
&(M)); \
@@ -43,7 +55,7 @@
((void)0)
#define __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,C) \
- if (C) { \
+ if (__infunc_need_locking) { \
_pthread_cleanup_pop_restore(&__infunc_pthread_cleanup_buffer,1); \
} \
} while (0)
diff --git a/libc/sysdeps/linux/common/bits/uClibc_pthread.h b/libc/sysdeps/linux/common/bits/uClibc_pthread.h
index 1d6209f5e..15aa1deed 100644
--- a/libc/sysdeps/linux/common/bits/uClibc_pthread.h
+++ b/libc/sysdeps/linux/common/bits/uClibc_pthread.h
@@ -28,6 +28,9 @@
#endif
#if defined _LIBC && (defined IS_IN_libc || defined NOT_IN_libc)
+
+struct _pthread_cleanup_buffer;
+
/* Threading functions internal to uClibc. Make these thread functions
* weak so that we can elide them from single-threaded processes. */
extern int weak_function __pthread_mutex_init (pthread_mutex_t *__mutex,
@@ -35,16 +38,14 @@ extern int weak_function __pthread_mutex_init (pthread_mutex_t *__mutex,
extern int weak_function __pthread_mutex_destroy (pthread_mutex_t *__mutex);
extern int weak_function __pthread_mutex_lock (pthread_mutex_t *__mutex);
extern int weak_function __pthread_mutex_unlock (pthread_mutex_t *__mutex);
-extern void __uclibc_mutex_unlock (void *) attribute_hidden;
extern int weak_function __pthread_mutex_trylock (pthread_mutex_t *__mutex);
-# ifndef __UCLIBC_HAS_THREADS_NATIVE__
extern void weak_function _pthread_cleanup_push_defer (
struct _pthread_cleanup_buffer *__buffer,
void (*__routine) (void *), void *__arg);
extern void weak_function _pthread_cleanup_pop_restore (
struct _pthread_cleanup_buffer *__buffer,
int __execute);
-# endif
+
#endif
#endif