1 /* Copyright (C) 2006 Manuel Novoa III <mjn3@codepoet.org> 2 * 3 * GNU Library General Public License (LGPL) version 2 or later. 4 * 5 * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details. 6 */ 7 8 #ifndef _UCLIBC_MUTEX_H 9 #define _UCLIBC_MUTEX_H 10 11 #include <features.h> 12 13 #ifdef __UCLIBC_HAS_THREADS__ 14 15 #include <pthread.h> 16 #ifdef _LIBC 17 #include <bits/uClibc_pthread.h> 18 #endif 19 20 #define __UCLIBC_MUTEX_TYPE pthread_mutex_t 21 22 #define __UCLIBC_MUTEX(M) pthread_mutex_t M 23 #define __UCLIBC_MUTEX_INIT(M,I) pthread_mutex_t M = I 24 #define __UCLIBC_MUTEX_STATIC(M,I) static pthread_mutex_t M = I 25 #define __UCLIBC_MUTEX_EXTERN(M) extern pthread_mutex_t M 26 27 #define __UCLIBC_MUTEX_INIT_VAR(M) \ 28 ((M) = (pthread_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) 29 30 #define __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(M) \ 31 __pthread_mutex_lock(&(M)) 32 33 #define __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(M) \ 34 __pthread_mutex_unlock(&(M)) 35 36 #define __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE(M) \ 37 __pthread_mutex_trylock(&(M)) 38 39 #define __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,C) \ 40 do { \ 41 struct _pthread_cleanup_buffer __infunc_pthread_cleanup_buffer; \ 42 int __infunc_need_locking = (C); \ 43 if (__infunc_need_locking) { \ 44 _pthread_cleanup_push_defer(&__infunc_pthread_cleanup_buffer, \ 45 (void (*) (void *))__pthread_mutex_unlock, \ 46 &(M)); \ 47 __pthread_mutex_lock(&(M)); \ 48 } \ 49 ((void)0) 50 51 #define __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,C) \ 52 if (__infunc_need_locking) { \ 53 _pthread_cleanup_pop_restore(&__infunc_pthread_cleanup_buffer,1); \ 54 } \ 55 } while (0) 56 57 #define __UCLIBC_MUTEX_AUTO_LOCK_VAR(A) int A 58 59 #define __UCLIBC_MUTEX_AUTO_LOCK(M,A,V) \ 60 __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,((A=(V)) == 0)) 61 62 #define __UCLIBC_MUTEX_AUTO_UNLOCK(M,A) \ 63 __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,(A == 0)) 64 65 #define __UCLIBC_MUTEX_LOCK(M) \ 66 __UCLIBC_MUTEX_CONDITIONAL_LOCK(M, 1) 67 68 #define __UCLIBC_MUTEX_UNLOCK(M) \ 69 __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M, 1) 70 71 #ifdef __USE_STDIO_FUTEXES__ 72 73 #include <bits/stdio-lock.h> 74 75 #define __UCLIBC_IO_MUTEX(M) _IO_lock_t M 76 #define __UCLIBC_IO_MUTEX_LOCK(M) _IO_lock_lock(M) 77 #define __UCLIBC_IO_MUTEX_UNLOCK(M) _IO_lock_unlock(M) 78 #define __UCLIBC_IO_MUTEX_TRYLOCK(M) _IO_lock_trylock(M) 79 #define __UCLIBC_IO_MUTEX_INIT(M) _IO_lock_t M = _IO_lock_initializer 80 #define __UCLIBC_IO_MUTEX_EXTERN(M) extern _IO_lock_t M 81 82 #define __UCLIBC_IO_MUTEX_CONDITIONAL_LOCK(M,C) \ 83 if (C) { \ 84 _IO_lock_lock(M); \ 85 } 86 87 #define __UCLIBC_IO_MUTEX_CONDITIONAL_UNLOCK(M,C) \ 88 if (C) { \ 89 _IO_lock_unlock(M); \ 90 } 91 92 #define __UCLIBC_IO_MUTEX_AUTO_LOCK(M,A,V) \ 93 __UCLIBC_IO_MUTEX_CONDITIONAL_LOCK(M,((A=(V))) == 0) 94 95 #define __UCLIBC_IO_MUTEX_AUTO_UNLOCK(M,A) \ 96 __UCLIBC_IO_MUTEX_CONDITIONAL_UNLOCK(M,((A) == 0)) 97 98 #define __UCLIBC_IO_MUTEX_LOCK_CANCEL_UNSAFE(M) _IO_lock_lock(M) 99 #define __UCLIBC_IO_MUTEX_UNLOCK_CANCEL_UNSAFE(M) _IO_lock_unlock(M) 100 101 #else /* of __USE_STDIO_FUTEXES__ */ 102 103 #define __UCLIBC_IO_MUTEX(M) __UCLIBC_MUTEX(M) 104 #define __UCLIBC_IO_MUTEX_LOCK(M) __UCLIBC_MUTEX_CONDITIONAL_LOCK(M, 1) 105 #define __UCLIBC_IO_MUTEX_UNLOCK(M) __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M, 1) 106 #define __UCLIBC_IO_MUTEX_TRYLOCK(M) __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE(M) 107 #define __UCLIBC_IO_MUTEX_INIT(M) __UCLIBC_MUTEX_INIT(M, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) 108 #define __UCLIBC_IO_MUTEX_EXTERN(M) __UCLIBC_MUTEX_EXTERN(M) 109 #define __UCLIBC_IO_MUTEX_AUTO_LOCK(M,A,V) __UCLIBC_MUTEX_AUTO_LOCK(M,A,V) 110 #define __UCLIBC_IO_MUTEX_AUTO_UNLOCK(M,A) __UCLIBC_MUTEX_AUTO_UNLOCK(M,A) 111 #define __UCLIBC_IO_MUTEX_LOCK_CANCEL_UNSAFE(M) __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(M) 112 #define __UCLIBC_IO_MUTEX_UNLOCK_CANCEL_UNSAFE(M) __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(M) 113 #define __UCLIBC_IO_MUTEX_CONDITIONAL_LOCK(M,C) __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,C) 114 #define __UCLIBC_IO_MUTEX_CONDITIONAL_UNLOCK(M,C) __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,C) 115 116 #endif /* of __USE_STDIO_FUTEXES__ */ 117 118 119 #else /* of __UCLIBC_HAS_THREADS__ */ 120 121 #define __UCLIBC_MUTEX(M) void *__UCLIBC_MUTEX_DUMMY_ ## M 122 #define __UCLIBC_MUTEX_INIT(M,I) extern void *__UCLIBC_MUTEX_DUMMY_ ## M 123 #define __UCLIBC_MUTEX_STATIC(M,I) extern void *__UCLIBC_MUTEX_DUMMY_ ## M 124 #define __UCLIBC_MUTEX_EXTERN(M) extern void *__UCLIBC_MUTEX_DUMMY_ ## M 125 126 #define __UCLIBC_MUTEX_INIT_VAR(M) ((void)0) 127 #define __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(M) ((void)0) 128 #define __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(M) ((void)0) 129 #define __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE(M) (0) /* Always succeed? */ 130 131 #define __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,C) ((void)0) 132 #define __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,C) ((void)0) 133 134 #define __UCLIBC_MUTEX_AUTO_LOCK_VAR(A) ((void)0) 135 #define __UCLIBC_MUTEX_AUTO_LOCK(M,A,V) ((void)0) 136 #define __UCLIBC_MUTEX_AUTO_UNLOCK(M,A) ((void)0) 137 138 #define __UCLIBC_MUTEX_LOCK(M) ((void)0) 139 #define __UCLIBC_MUTEX_UNLOCK(M) ((void)0) 140 141 #define __UCLIBC_IO_MUTEX(M) __UCLIBC_MUTEX(M) 142 #define __UCLIBC_IO_MUTEX_LOCK(M) __UCLIBC_MUTEX_CONDITIONAL_LOCK(M, 1) 143 #define __UCLIBC_IO_MUTEX_UNLOCK(M) __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M, 1) 144 #define __UCLIBC_IO_MUTEX_TRYLOCK(M) __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE(M) 145 #define __UCLIBC_IO_MUTEX_INIT(M) __UCLIBC_MUTEX_INIT(M, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) 146 #define __UCLIBC_IO_MUTEX_EXTERN(M) __UCLIBC_MUTEX_EXTERN(M) 147 #define __UCLIBC_IO_MUTEX_AUTO_LOCK(M,A,V) __UCLIBC_MUTEX_AUTO_LOCK(M,A,V) 148 #define __UCLIBC_IO_MUTEX_AUTO_UNLOCK(M,A) __UCLIBC_MUTEX_AUTO_UNLOCK(M,A) 149 #define __UCLIBC_IO_MUTEX_LOCK_CANCEL_UNSAFE(M) __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(M) 150 #define __UCLIBC_IO_MUTEX_UNLOCK_CANCEL_UNSAFE(M) __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(M) 151 #define __UCLIBC_IO_MUTEX_CONDITIONAL_LOCK(M,C) __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,C) 152 #define __UCLIBC_IO_MUTEX_CONDITIONAL_UNLOCK(M,C) __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,C) 153 154 #endif /* of __UCLIBC_HAS_THREADS__ */ 155 156 #define __UCLIBC_IO_MUTEX_TRYLOCK_CANCEL_UNSAFE(M) \ 157 __UCLIBC_IO_MUTEX_TRYLOCK(M) 158 159 #endif /* _UCLIBC_MUTEX_H */ 160