1 /* libc-internal interface for mutex locks. LinuxThreads version. 2 Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Library General Public License as 7 published by the Free Software Foundation; either version 2 of the 8 License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Library General Public License for more details. 14 15 You should have received a copy of the GNU Library General Public 16 License along with the GNU C Library; see the file COPYING.LIB. If not, 17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 Boston, MA 02111-1307, USA. */ 19 20 #ifndef _BITS_LIBC_LOCK_H 21 #define _BITS_LIBC_LOCK_H 1 22 23 #include <pthread.h> 24 25 /* Mutex type. */ 26 #if defined(_LIBC) || defined(_IO_MTSAFE_IO) 27 typedef pthread_mutex_t __libc_lock_t; 28 typedef struct { pthread_mutex_t mutex; } __libc_lock_recursive_t; 29 # ifdef __USE_UNIX98 30 typedef pthread_rwlock_t __libc_rwlock_t; 31 # else 32 typedef struct __libc_rwlock_opaque__ __libc_rwlock_t; 33 # endif 34 #else 35 typedef struct __libc_lock_opaque__ __libc_lock_t; 36 typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t; 37 typedef struct __libc_rwlock_opaque__ __libc_rwlock_t; 38 #endif 39 40 /* Type for key to thread-specific data. */ 41 typedef pthread_key_t __libc_key_t; 42 43 /* Define a lock variable NAME with storage class CLASS. The lock must be 44 initialized with __libc_lock_init before it can be used (or define it 45 with __libc_lock_define_initialized, below). Use `extern' for CLASS to 46 declare a lock defined in another module. In public structure 47 definitions you must use a pointer to the lock structure (i.e., NAME 48 begins with a `*'), because its storage size will not be known outside 49 of libc. */ 50 #define __libc_lock_define(CLASS,NAME) \ 51 CLASS __libc_lock_t NAME; 52 #define __libc_rwlock_define(CLASS,NAME) \ 53 CLASS __libc_rwlock_t NAME; 54 #define __libc_lock_define_recursive(CLASS,NAME) \ 55 CLASS __libc_lock_recursive_t NAME; 56 57 /* Define an initialized lock variable NAME with storage class CLASS. 58 59 For the C library we take a deeper look at the initializer. For 60 this implementation all fields are initialized to zero. Therefore 61 we don't initialize the variable which allows putting it into the 62 BSS section. (Except on PA-RISC and other odd architectures, where 63 initialized locks must be set to one due to the lack of normal 64 atomic operations.) */ 65 66 #if __LT_SPINLOCK_INIT == 0 67 # define __libc_lock_define_initialized(CLASS,NAME) \ 68 CLASS __libc_lock_t NAME; 69 #else 70 # define __libc_lock_define_initialized(CLASS,NAME) \ 71 CLASS __libc_lock_t NAME = PTHREAD_MUTEX_INITIALIZER; 72 #endif 73 74 #define __libc_rwlock_define_initialized(CLASS,NAME) \ 75 CLASS __libc_rwlock_t NAME = PTHREAD_RWLOCK_INITIALIZER; 76 77 /* Define an initialized recursive lock variable NAME with storage 78 class CLASS. */ 79 #define __libc_lock_define_initialized_recursive(CLASS,NAME) \ 80 CLASS __libc_lock_recursive_t NAME = _LIBC_LOCK_RECURSIVE_INITIALIZER; 81 #define _LIBC_LOCK_RECURSIVE_INITIALIZER \ 82 {PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP} 83 84 /* Initialize the named lock variable, leaving it in a consistent, unlocked 85 state. */ 86 #define __libc_lock_init(NAME) \ 87 (__pthread_mutex_init != NULL ? __pthread_mutex_init (&(NAME), NULL) : 0); 88 #define __libc_rwlock_init(NAME) \ 89 (__pthread_rwlock_init != NULL ? __pthread_rwlock_init (&(NAME), NULL) : 0); 90 91 /* Same as last but this time we initialize a recursive mutex. */ 92 #define __libc_lock_init_recursive(NAME) \ 93 do { \ 94 if (__pthread_mutex_init != NULL) \ 95 { \ 96 pthread_mutexattr_t __attr; \ 97 __pthread_mutexattr_init (&__attr); \ 98 __pthread_mutexattr_settype (&__attr, PTHREAD_MUTEX_RECURSIVE_NP); \ 99 __pthread_mutex_init (&(NAME).mutex, &__attr); \ 100 __pthread_mutexattr_destroy (&__attr); \ 101 } \ 102 } while (0); 103 104 /* Finalize the named lock variable, which must be locked. It cannot be 105 used again until __libc_lock_init is called again on it. This must be 106 called on a lock variable before the containing storage is reused. */ 107 #define __libc_lock_fini(NAME) \ 108 (__pthread_mutex_destroy != NULL ? __pthread_mutex_destroy (&(NAME)) : 0); 109 #define __libc_rwlock_fini(NAME) \ 110 (__pthread_rwlock_destroy != NULL ? __pthread_rwlock_destroy (&(NAME)) : 0); 111 112 /* Finalize recursive named lock. */ 113 #define __libc_lock_fini_recursive(NAME) __libc_lock_fini ((NAME).mutex) 114 115 /* Lock the named lock variable. */ 116 #define __libc_lock_lock(NAME) \ 117 (__pthread_mutex_lock != NULL ? __pthread_mutex_lock (&(NAME)) : 0); 118 #define __libc_rwlock_rdlock(NAME) \ 119 (__pthread_rwlock_rdlock != NULL ? __pthread_rwlock_rdlock (&(NAME)) : 0); 120 #define __libc_rwlock_wrlock(NAME) \ 121 (__pthread_rwlock_wrlock != NULL ? __pthread_rwlock_wrlock (&(NAME)) : 0); 122 123 /* Lock the recursive named lock variable. */ 124 #define __libc_lock_lock_recursive(NAME) __libc_lock_lock ((NAME).mutex) 125 126 /* Try to lock the named lock variable. */ 127 #define __libc_lock_trylock(NAME) \ 128 (__pthread_mutex_trylock != NULL ? __pthread_mutex_trylock (&(NAME)) : 0) 129 #define __libc_rwlock_tryrdlock(NAME) \ 130 (__pthread_rwlock_tryrdlock != NULL \ 131 ? __pthread_rwlock_tryrdlock (&(NAME)) : 0) 132 #define __libc_rwlock_trywrlock(NAME) \ 133 (__pthread_rwlock_trywrlock != NULL \ 134 ? __pthread_rwlock_trywrlock (&(NAME)) : 0) 135 136 /* Try to lock the recursive named lock variable. */ 137 #define __libc_lock_trylock_recursive(NAME) __libc_lock_trylock ((NAME).mutex) 138 139 /* Unlock the named lock variable. */ 140 #define __libc_lock_unlock(NAME) \ 141 (__pthread_mutex_unlock != NULL ? __pthread_mutex_unlock (&(NAME)) : 0); 142 #define __libc_rwlock_unlock(NAME) \ 143 (__pthread_rwlock_unlock != NULL ? __pthread_rwlock_unlock (&(NAME)) : 0); 144 145 /* Unlock the recursive named lock variable. */ 146 #define __libc_lock_unlock_recursive(NAME) __libc_lock_unlock ((NAME).mutex) 147 148 149 /* Define once control variable. */ 150 #if PTHREAD_ONCE_INIT == 0 151 /* Special case for static variables where we can avoid the initialization 152 if it is zero. */ 153 # define __libc_once_define(CLASS, NAME) \ 154 CLASS pthread_once_t NAME 155 #else 156 # define __libc_once_define(CLASS, NAME) \ 157 CLASS pthread_once_t NAME = PTHREAD_ONCE_INIT 158 #endif 159 160 /* Call handler iff the first call. */ 161 #define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \ 162 do { \ 163 if (__pthread_once != NULL) \ 164 __pthread_once (&(ONCE_CONTROL), (INIT_FUNCTION)); \ 165 else if ((ONCE_CONTROL) == PTHREAD_ONCE_INIT) { \ 166 INIT_FUNCTION (); \ 167 (ONCE_CONTROL) = !PTHREAD_ONCE_INIT; \ 168 } \ 169 } while (0) 170 171 172 /* Start critical region with cleanup. */ 173 #define __libc_cleanup_region_start(DOIT, FCT, ARG) \ 174 { struct _pthread_cleanup_buffer _buffer; \ 175 int _avail = (DOIT) && _pthread_cleanup_push_defer != NULL; \ 176 if (_avail) { \ 177 _pthread_cleanup_push_defer (&_buffer, (FCT), (ARG)); \ 178 } 179 180 /* End critical region with cleanup. */ 181 #define __libc_cleanup_region_end(DOIT) \ 182 if (_avail) { \ 183 _pthread_cleanup_pop_restore (&_buffer, (DOIT)); \ 184 } \ 185 } 186 187 /* Sometimes we have to exit the block in the middle. */ 188 #define __libc_cleanup_end(DOIT) \ 189 if (_avail) { \ 190 _pthread_cleanup_pop_restore (&_buffer, (DOIT)); \ 191 } 192 193 /* Create thread-specific key. */ 194 #define __libc_key_create(KEY, DESTRUCTOR) \ 195 (__pthread_key_create != NULL ? __pthread_key_create (KEY, DESTRUCTOR) : 1) 196 197 /* Get thread-specific data. */ 198 #define __libc_getspecific(KEY) \ 199 (__pthread_getspecific != NULL ? __pthread_getspecific (KEY) : NULL) 200 201 /* Set thread-specific data. */ 202 #define __libc_setspecific(KEY, VALUE) \ 203 (__pthread_setspecific != NULL ? __pthread_setspecific (KEY, VALUE) : 0) 204 205 206 /* Register handlers to execute before and after `fork'. */ 207 #define __libc_atfork(PREPARE, PARENT, CHILD) \ 208 (__pthread_atfork != NULL ? __pthread_atfork (PREPARE, PARENT, CHILD) : 0) 209 210 /* Functions that are used by this file and are internal to the GNU C 211 library. */ 212 213 extern int __pthread_mutex_init (pthread_mutex_t *__mutex, 214 __const pthread_mutexattr_t *__mutex_attr); 215 216 extern int __pthread_mutex_destroy (pthread_mutex_t *__mutex); 217 218 extern int __pthread_mutex_trylock (pthread_mutex_t *__mutex); 219 220 extern int __pthread_mutex_lock (pthread_mutex_t *__mutex); 221 222 extern int __pthread_mutex_unlock (pthread_mutex_t *__mutex); 223 224 extern int __pthread_mutexattr_init (pthread_mutexattr_t *__attr); 225 226 extern int __pthread_mutexattr_destroy (pthread_mutexattr_t *__attr); 227 228 extern int __pthread_mutexattr_settype (pthread_mutexattr_t *__attr, 229 int __kind); 230 231 #ifdef __USE_UNIX98 232 extern int __pthread_rwlock_init (pthread_rwlock_t *__rwlock, 233 __const pthread_rwlockattr_t *__attr); 234 235 extern int __pthread_rwlock_destroy (pthread_rwlock_t *__rwlock); 236 237 extern int __pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock); 238 239 extern int __pthread_rwlock_tryrdlock (pthread_rwlock_t *__rwlock); 240 241 extern int __pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock); 242 243 extern int __pthread_rwlock_trywrlock (pthread_rwlock_t *__rwlock); 244 245 extern int __pthread_rwlock_unlock (pthread_rwlock_t *__rwlock); 246 #endif 247 248 extern int __pthread_key_create (pthread_key_t *__key, 249 void (*__destr_function) (void *)); 250 251 extern int __pthread_setspecific (pthread_key_t __key, 252 __const void *__pointer); 253 254 extern void *__pthread_getspecific (pthread_key_t __key); 255 256 extern int __pthread_once (pthread_once_t *__once_control, 257 void (*__init_routine) (void)); 258 259 extern int __pthread_atfork (void (*__prepare) (void), 260 void (*__parent) (void), 261 void (*__child) (void)); 262 263 264 265 /* Make the pthread functions weak so that we can elide them from 266 single-threaded processes. */ 267 #ifndef __NO_WEAK_PTHREAD_ALIASES 268 # pragma weak __pthread_mutex_init 269 # pragma weak __pthread_mutex_destroy 270 # pragma weak __pthread_mutex_lock 271 # pragma weak __pthread_mutex_trylock 272 # pragma weak __pthread_mutex_unlock 273 # pragma weak __pthread_mutexattr_init 274 # pragma weak __pthread_mutexattr_destroy 275 # pragma weak __pthread_mutexattr_settype 276 # pragma weak __pthread_rwlock_destroy 277 # pragma weak __pthread_rwlock_rdlock 278 # pragma weak __pthread_rwlock_tryrdlock 279 # pragma weak __pthread_rwlock_wrlock 280 # pragma weak __pthread_rwlock_trywrlock 281 # pragma weak __pthread_rwlock_unlock 282 # pragma weak __pthread_key_create 283 # pragma weak __pthread_setspecific 284 # pragma weak __pthread_getspecific 285 # pragma weak __pthread_once 286 # pragma weak __pthread_initialize 287 # pragma weak __pthread_atfork 288 # pragma weak _pthread_cleanup_push_defer 289 # pragma weak _pthread_cleanup_pop_restore 290 # endif 291 #endif 292 293 /* We need portable names for some functions. E.g., when they are 294 used as argument to __libc_cleanup_region_start. */ 295 #define __libc_mutex_unlock __pthread_mutex_unlock 296 297 #endif /* bits/libc-lock.h */ 298