diff options
Diffstat (limited to 'libc/sysdeps/linux')
-rw-r--r-- | libc/sysdeps/linux/common/bits/uClibc_mutex.h | 22 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/bits/uClibc_pthread.h | 7 |
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 |