00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #ifndef _ASTERISK_LOCK_H
00049 #define _ASTERISK_LOCK_H
00050
00051 #include <pthread.h>
00052 #include <time.h>
00053 #include <sys/param.h>
00054 #ifdef HAVE_BKTR
00055 #include <execinfo.h>
00056 #endif
00057
00058 #ifndef HAVE_PTHREAD_RWLOCK_TIMEDWRLOCK
00059 #include "asterisk/time.h"
00060 #endif
00061
00062 #include "asterisk/logger.h"
00063 #include "asterisk/compiler.h"
00064
00065 #define AST_PTHREADT_NULL (pthread_t) -1
00066 #define AST_PTHREADT_STOP (pthread_t) -2
00067
00068 #if (defined(SOLARIS) || defined(BSD))
00069 #define AST_MUTEX_INIT_W_CONSTRUCTORS
00070 #endif
00071
00072
00073
00074 #if defined(HAVE_PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) && defined(HAVE_PTHREAD_MUTEX_RECURSIVE_NP)
00075 #define PTHREAD_MUTEX_INIT_VALUE PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
00076 #define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE_NP
00077 #else
00078 #define PTHREAD_MUTEX_INIT_VALUE PTHREAD_MUTEX_INITIALIZER
00079 #define AST_MUTEX_KIND PTHREAD_MUTEX_RECURSIVE
00080 #endif
00081
00082 #ifdef HAVE_PTHREAD_RWLOCK_INITIALIZER
00083 #define __AST_RWLOCK_INIT_VALUE PTHREAD_RWLOCK_INITIALIZER
00084 #else
00085 #define __AST_RWLOCK_INIT_VALUE {0}
00086 #endif
00087
00088 #ifdef HAVE_BKTR
00089 #define AST_LOCK_TRACK_INIT_VALUE { { NULL }, { 0 }, 0, { NULL }, { 0 }, {{{ 0 }}}, PTHREAD_MUTEX_INIT_VALUE }
00090 #else
00091 #define AST_LOCK_TRACK_INIT_VALUE { { NULL }, { 0 }, 0, { NULL }, { 0 }, PTHREAD_MUTEX_INIT_VALUE }
00092 #endif
00093
00094 #define AST_MUTEX_INIT_VALUE { PTHREAD_MUTEX_INIT_VALUE, NULL, 1 }
00095 #define AST_MUTEX_INIT_VALUE_NOTRACKING { PTHREAD_MUTEX_INIT_VALUE, NULL, 0 }
00096
00097 #define AST_RWLOCK_INIT_VALUE { __AST_RWLOCK_INIT_VALUE, NULL, 1 }
00098 #define AST_RWLOCK_INIT_VALUE_NOTRACKING { __AST_RWLOCK_INIT_VALUE, NULL, 0 }
00099
00100 #define AST_MAX_REENTRANCY 10
00101
00102 struct ast_channel;
00103
00104 struct ast_lock_track {
00105 const char *file[AST_MAX_REENTRANCY];
00106 int lineno[AST_MAX_REENTRANCY];
00107 int reentrancy;
00108 const char *func[AST_MAX_REENTRANCY];
00109 pthread_t thread[AST_MAX_REENTRANCY];
00110 #ifdef HAVE_BKTR
00111 struct ast_bt backtrace[AST_MAX_REENTRANCY];
00112 #endif
00113 pthread_mutex_t reentr_mutex;
00114 };
00115
00116
00117
00118
00119
00120
00121 struct ast_mutex_info {
00122 pthread_mutex_t mutex;
00123
00124 struct ast_lock_track *track;
00125 unsigned int tracking:1;
00126 };
00127
00128
00129
00130
00131
00132
00133 struct ast_rwlock_info {
00134 pthread_rwlock_t lock;
00135
00136 struct ast_lock_track *track;
00137 unsigned int tracking:1;
00138 };
00139
00140 typedef struct ast_mutex_info ast_mutex_t;
00141
00142 typedef struct ast_rwlock_info ast_rwlock_t;
00143
00144 typedef pthread_cond_t ast_cond_t;
00145
00146 int __ast_pthread_mutex_init(int tracking, const char *filename, int lineno, const char *func, const char *mutex_name, ast_mutex_t *t);
00147 int __ast_pthread_mutex_destroy(const char *filename, int lineno, const char *func, const char *mutex_name, ast_mutex_t *t);
00148 int __ast_pthread_mutex_lock(const char *filename, int lineno, const char *func, const char* mutex_name, ast_mutex_t *t);
00149 int __ast_pthread_mutex_trylock(const char *filename, int lineno, const char *func, const char* mutex_name, ast_mutex_t *t);
00150 int __ast_pthread_mutex_unlock(const char *filename, int lineno, const char *func, const char *mutex_name, ast_mutex_t *t);
00151
00152 #define ast_mutex_init(pmutex) __ast_pthread_mutex_init(1, __FILE__, __LINE__, __PRETTY_FUNCTION__, #pmutex, pmutex)
00153 #define ast_mutex_init_notracking(pmutex) __ast_pthread_mutex_init(0, __FILE__, __LINE__, __PRETTY_FUNCTION__, #pmutex, pmutex)
00154 #define ast_mutex_destroy(a) __ast_pthread_mutex_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
00155 #define ast_mutex_lock(a) __ast_pthread_mutex_lock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
00156 #define ast_mutex_unlock(a) __ast_pthread_mutex_unlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
00157 #define ast_mutex_trylock(a) __ast_pthread_mutex_trylock(__FILE__, __LINE__, __PRETTY_FUNCTION__, #a, a)
00158
00159
00160 int __ast_cond_init(const char *filename, int lineno, const char *func, const char *cond_name, ast_cond_t *cond, pthread_condattr_t *cond_attr);
00161 int __ast_cond_signal(const char *filename, int lineno, const char *func, const char *cond_name, ast_cond_t *cond);
00162 int __ast_cond_broadcast(const char *filename, int lineno, const char *func, const char *cond_name, ast_cond_t *cond);
00163 int __ast_cond_destroy(const char *filename, int lineno, const char *func, const char *cond_name, ast_cond_t *cond);
00164 int __ast_cond_wait(const char *filename, int lineno, const char *func, const char *cond_name, const char *mutex_name, ast_cond_t *cond, ast_mutex_t *t);
00165 int __ast_cond_timedwait(const char *filename, int lineno, const char *func, const char *cond_name, const char *mutex_name, ast_cond_t *cond, ast_mutex_t *t, const struct timespec *abstime);
00166
00167 #define ast_cond_init(cond, attr) __ast_cond_init(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond, attr)
00168 #define ast_cond_destroy(cond) __ast_cond_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
00169 #define ast_cond_signal(cond) __ast_cond_signal(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
00170 #define ast_cond_broadcast(cond) __ast_cond_broadcast(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, cond)
00171 #define ast_cond_wait(cond, mutex) __ast_cond_wait(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #mutex, cond, mutex)
00172 #define ast_cond_timedwait(cond, mutex, time) __ast_cond_timedwait(__FILE__, __LINE__, __PRETTY_FUNCTION__, #cond, #mutex, cond, mutex, time)
00173
00174
00175 int __ast_rwlock_init(int tracking, const char *filename, int lineno, const char *func, const char *rwlock_name, ast_rwlock_t *t);
00176 int __ast_rwlock_destroy(const char *filename, int lineno, const char *func, const char *rwlock_name, ast_rwlock_t *t);
00177 int __ast_rwlock_unlock(const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name);
00178 int __ast_rwlock_rdlock(const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name);
00179 int __ast_rwlock_wrlock(const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name);
00180 int __ast_rwlock_timedrdlock(const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name, const struct timespec *abs_timeout);
00181 int __ast_rwlock_timedwrlock(const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name, const struct timespec *abs_timeout);
00182 int __ast_rwlock_tryrdlock(const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name);
00183 int __ast_rwlock_trywrlock(const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name);
00184
00185
00186
00187
00188
00189
00190 #define ast_rwlock_init(rwlock) __ast_rwlock_init(1, __FILE__, __LINE__, __PRETTY_FUNCTION__, #rwlock, rwlock)
00191
00192
00193
00194
00195
00196
00197 #define ast_rwlock_init_notracking(rwlock) __ast_rwlock_init(0, __FILE__, __LINE__, __PRETTY_FUNCTION__, #rwlock, rwlock)
00198
00199 #define ast_rwlock_destroy(rwlock) __ast_rwlock_destroy(__FILE__, __LINE__, __PRETTY_FUNCTION__, #rwlock, rwlock)
00200 #define ast_rwlock_unlock(a) __ast_rwlock_unlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, #a)
00201 #define ast_rwlock_rdlock(a) __ast_rwlock_rdlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, #a)
00202 #define ast_rwlock_wrlock(a) __ast_rwlock_wrlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, #a)
00203 #define ast_rwlock_tryrdlock(a) __ast_rwlock_tryrdlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, #a)
00204 #define ast_rwlock_trywrlock(a) __ast_rwlock_trywrlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, #a)
00205 #define ast_rwlock_timedrdlock(a, b) __ast_rwlock_timedrdlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, #a, b)
00206 #define ast_rwlock_timedwrlock(a, b) __ast_rwlock_timedwrlock(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, #a, b)
00207
00208 #define ROFFSET ((lt->reentrancy > 0) ? (lt->reentrancy-1) : 0)
00209
00210 #ifdef DEBUG_THREADS
00211
00212 #define __ast_mutex_logger(...) do { if (canlog) ast_log(LOG_ERROR, __VA_ARGS__); else fprintf(stderr, __VA_ARGS__); } while (0)
00213
00214 #ifdef THREAD_CRASH
00215 #define DO_THREAD_CRASH do { *((int *)(0)) = 1; } while(0)
00216 #else
00217 #define DO_THREAD_CRASH do { } while (0)
00218 #endif
00219
00220 #include <errno.h>
00221
00222 enum ast_lock_type {
00223 AST_MUTEX,
00224 AST_RDLOCK,
00225 AST_WRLOCK,
00226 };
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 #if !defined(LOW_MEMORY)
00237 #ifdef HAVE_BKTR
00238 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
00239 int line_num, const char *func, const char *lock_name, void *lock_addr, struct ast_bt *bt);
00240 #else
00241 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
00242 int line_num, const char *func, const char *lock_name, void *lock_addr);
00243 #endif
00244
00245 #else
00246
00247 #ifdef HAVE_BKTR
00248 #define ast_store_lock_info(I,DONT,CARE,ABOUT,THE,PARAMETERS,BUD)
00249 #else
00250 #define ast_store_lock_info(I,DONT,CARE,ABOUT,THE,PARAMETERS)
00251 #endif
00252 #endif
00253
00254
00255
00256
00257 #if !defined(LOW_MEMORY)
00258 void ast_mark_lock_acquired(void *lock_addr);
00259 #else
00260 #define ast_mark_lock_acquired(ignore)
00261 #endif
00262
00263
00264
00265
00266 #if !defined(LOW_MEMORY)
00267 void ast_mark_lock_failed(void *lock_addr);
00268 #else
00269 #define ast_mark_lock_failed(ignore)
00270 #endif
00271
00272
00273
00274
00275
00276
00277
00278 #if !defined(LOW_MEMORY)
00279 #ifdef HAVE_BKTR
00280 void ast_remove_lock_info(void *lock_addr, struct ast_bt *bt);
00281 #else
00282 void ast_remove_lock_info(void *lock_addr);
00283 #endif
00284 void ast_suspend_lock_info(void *lock_addr);
00285 void ast_restore_lock_info(void *lock_addr);
00286 #else
00287 #ifdef HAVE_BKTR
00288 #define ast_remove_lock_info(ignore,me)
00289 #else
00290 #define ast_remove_lock_info(ignore)
00291 #endif
00292 #define ast_suspend_lock_info(ignore);
00293 #define ast_restore_lock_info(ignore);
00294 #endif
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 void log_show_lock(void *this_lock_addr);
00307
00308
00309
00310
00311
00312
00313
00314 #if !defined(LOW_MEMORY)
00315 int ast_find_lock_info(void *lock_addr, char *filename, size_t filename_size, int *lineno, char *func, size_t func_size, char *mutex_name, size_t mutex_name_size);
00316 #else
00317 #define ast_find_lock_info(a,b,c,d,e,f,g,h) -1
00318 #endif
00319
00320
00321
00322
00323
00324
00325
00326 #define CHANNEL_DEADLOCK_AVOIDANCE(chan) \
00327 do { \
00328 char __filename[80], __func[80], __mutex_name[80]; \
00329 int __lineno; \
00330 int __res = ast_find_lock_info(ao2_object_get_lockaddr(chan), __filename, sizeof(__filename), &__lineno, __func, sizeof(__func), __mutex_name, sizeof(__mutex_name)); \
00331 int __res2 = ast_channel_unlock(chan); \
00332 usleep(1); \
00333 if (__res < 0) { \
00334 if (__res2) { \
00335 ast_log(LOG_WARNING, "Could not unlock channel '%s': %s and no lock info found! I will NOT try to relock.\n", #chan, strerror(__res2)); \
00336 } else { \
00337 ast_channel_lock(chan); \
00338 } \
00339 } else { \
00340 if (__res2) { \
00341 ast_log(LOG_WARNING, "Could not unlock channel '%s': %s. {{{Originally locked at %s line %d: (%s) '%s'}}} I will NOT try to relock.\n", #chan, strerror(__res2), __filename, __lineno, __func, __mutex_name); \
00342 } else { \
00343 __ao2_lock(chan, __filename, __func, __lineno, __mutex_name); \
00344 } \
00345 } \
00346 } while (0)
00347
00348 #define DEADLOCK_AVOIDANCE(lock) \
00349 do { \
00350 char __filename[80], __func[80], __mutex_name[80]; \
00351 int __lineno; \
00352 int __res = ast_find_lock_info(lock, __filename, sizeof(__filename), &__lineno, __func, sizeof(__func), __mutex_name, sizeof(__mutex_name)); \
00353 int __res2 = ast_mutex_unlock(lock); \
00354 usleep(1); \
00355 if (__res < 0) { \
00356 if (__res2 == 0) { \
00357 ast_mutex_lock(lock); \
00358 } else { \
00359 ast_log(LOG_WARNING, "Could not unlock mutex '%s': %s and no lock info found! I will NOT try to relock.\n", #lock, strerror(__res2)); \
00360 } \
00361 } else { \
00362 if (__res2 == 0) { \
00363 __ast_pthread_mutex_lock(__filename, __lineno, __func, __mutex_name, lock); \
00364 } else { \
00365 ast_log(LOG_WARNING, "Could not unlock mutex '%s': %s. {{{Originally locked at %s line %d: (%s) '%s'}}} I will NOT try to relock.\n", #lock, strerror(__res2), __filename, __lineno, __func, __mutex_name); \
00366 } \
00367 } \
00368 } while (0)
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 #define DLA_UNLOCK(lock) \
00383 do { \
00384 char __filename[80], __func[80], __mutex_name[80]; \
00385 int __lineno; \
00386 int __res = ast_find_lock_info(lock, __filename, sizeof(__filename), &__lineno, __func, sizeof(__func), __mutex_name, sizeof(__mutex_name)); \
00387 int __res2 = ast_mutex_unlock(lock);
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 #define DLA_LOCK(lock) \
00402 if (__res < 0) { \
00403 if (__res2) { \
00404 ast_log(LOG_WARNING, "Could not unlock mutex '%s': %s and no lock info found! I will NOT try to relock.\n", #lock, strerror(__res2)); \
00405 } else { \
00406 ast_mutex_lock(lock); \
00407 } \
00408 } else { \
00409 if (__res2) { \
00410 ast_log(LOG_WARNING, "Could not unlock mutex '%s': %s. {{{Originally locked at %s line %d: (%s) '%s'}}} I will NOT try to relock.\n", #lock, strerror(__res2), __filename, __lineno, __func, __mutex_name); \
00411 } else { \
00412 __ast_pthread_mutex_lock(__filename, __lineno, __func, __mutex_name, lock); \
00413 } \
00414 } \
00415 } while (0)
00416
00417 static inline void ast_reentrancy_lock(struct ast_lock_track *lt)
00418 {
00419 int res;
00420 if ((res = pthread_mutex_lock(<->reentr_mutex))) {
00421 fprintf(stderr, "ast_reentrancy_lock failed: '%s' (%d)\n", strerror(res), res);
00422 #if defined(DO_CRASH) || defined(THREAD_CRASH)
00423 abort();
00424 #endif
00425 }
00426 }
00427
00428 static inline void ast_reentrancy_unlock(struct ast_lock_track *lt)
00429 {
00430 int res;
00431 if ((res = pthread_mutex_unlock(<->reentr_mutex))) {
00432 fprintf(stderr, "ast_reentrancy_unlock failed: '%s' (%d)\n", strerror(res), res);
00433 #if defined(DO_CRASH) || defined(THREAD_CRASH)
00434 abort();
00435 #endif
00436 }
00437 }
00438
00439 static inline void ast_reentrancy_init(struct ast_lock_track **plt)
00440 {
00441 int i;
00442 pthread_mutexattr_t reentr_attr;
00443 struct ast_lock_track *lt = *plt;
00444
00445 if (!lt) {
00446 lt = *plt = (struct ast_lock_track *) calloc(1, sizeof(*lt));
00447 }
00448
00449 for (i = 0; i < AST_MAX_REENTRANCY; i++) {
00450 lt->file[i] = NULL;
00451 lt->lineno[i] = 0;
00452 lt->func[i] = NULL;
00453 lt->thread[i] = 0;
00454 #ifdef HAVE_BKTR
00455 memset(<->backtrace[i], 0, sizeof(lt->backtrace[i]));
00456 #endif
00457 }
00458
00459 lt->reentrancy = 0;
00460
00461 pthread_mutexattr_init(&reentr_attr);
00462 pthread_mutexattr_settype(&reentr_attr, AST_MUTEX_KIND);
00463 pthread_mutex_init(<->reentr_mutex, &reentr_attr);
00464 pthread_mutexattr_destroy(&reentr_attr);
00465 }
00466
00467 static inline void delete_reentrancy_cs(struct ast_lock_track **plt)
00468 {
00469 struct ast_lock_track *lt;
00470 if (*plt) {
00471 lt = *plt;
00472 pthread_mutex_destroy(<->reentr_mutex);
00473 free(lt);
00474 *plt = NULL;
00475 }
00476 }
00477
00478 #else
00479
00480 #define CHANNEL_DEADLOCK_AVOIDANCE(chan) \
00481 ast_channel_unlock(chan); \
00482 usleep(1); \
00483 ast_channel_lock(chan);
00484
00485 #define DEADLOCK_AVOIDANCE(lock) \
00486 do { \
00487 int __res; \
00488 if (!(__res = ast_mutex_unlock(lock))) { \
00489 usleep(1); \
00490 ast_mutex_lock(lock); \
00491 } else { \
00492 ast_log(LOG_WARNING, "Failed to unlock mutex '%s' (%s). I will NOT try to relock. {{{ THIS IS A BUG. }}}\n", #lock, strerror(__res)); \
00493 } \
00494 } while (0)
00495
00496 #define DLA_UNLOCK(lock) ast_mutex_unlock(lock)
00497
00498 #define DLA_LOCK(lock) ast_mutex_lock(lock)
00499
00500 #endif
00501
00502 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
00503
00504
00505
00506
00507 #define __AST_MUTEX_DEFINE(scope, mutex, init_val, track) \
00508 scope ast_mutex_t mutex = init_val; \
00509 static void __attribute__((constructor)) init_##mutex(void) \
00510 { \
00511 if (track) \
00512 ast_mutex_init(&mutex); \
00513 else \
00514 ast_mutex_init_notracking(&mutex); \
00515 } \
00516 \
00517 static void __attribute__((destructor)) fini_##mutex(void) \
00518 { \
00519 ast_mutex_destroy(&mutex); \
00520 }
00521 #else
00522
00523 #define __AST_MUTEX_DEFINE(scope, mutex, init_val, track) scope ast_mutex_t mutex = init_val
00524 #endif
00525
00526 #define AST_MUTEX_DEFINE_STATIC(mutex) __AST_MUTEX_DEFINE(static, mutex, AST_MUTEX_INIT_VALUE, 1)
00527 #define AST_MUTEX_DEFINE_STATIC_NOTRACKING(mutex) __AST_MUTEX_DEFINE(static, mutex, AST_MUTEX_INIT_VALUE_NOTRACKING, 0)
00528
00529
00530
00531 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
00532 #define __AST_RWLOCK_DEFINE(scope, rwlock, init_val, track) \
00533 scope ast_rwlock_t rwlock = init_val; \
00534 static void __attribute__((constructor)) init_##rwlock(void) \
00535 { \
00536 if (track) \
00537 ast_rwlock_init(&rwlock); \
00538 else \
00539 ast_rwlock_init_notracking(&rwlock); \
00540 } \
00541 static void __attribute__((destructor)) fini_##rwlock(void) \
00542 { \
00543 ast_rwlock_destroy(&rwlock); \
00544 }
00545 #else
00546 #define __AST_RWLOCK_DEFINE(scope, rwlock, init_val, track) scope ast_rwlock_t rwlock = init_val
00547 #endif
00548
00549 #define AST_RWLOCK_DEFINE_STATIC(rwlock) __AST_RWLOCK_DEFINE(static, rwlock, AST_RWLOCK_INIT_VALUE, 1)
00550 #define AST_RWLOCK_DEFINE_STATIC_NOTRACKING(rwlock) __AST_RWLOCK_DEFINE(static, rwlock, AST_RWLOCK_INIT_VALUE_NOTRACKING, 0)
00551
00552 #ifndef __CYGWIN__
00553 #define pthread_mutex_t use_ast_mutex_t_instead_of_pthread_mutex_t
00554 #define pthread_cond_t use_ast_cond_t_instead_of_pthread_cond_t
00555 #endif
00556 #define pthread_mutex_lock use_ast_mutex_lock_instead_of_pthread_mutex_lock
00557 #define pthread_mutex_unlock use_ast_mutex_unlock_instead_of_pthread_mutex_unlock
00558 #define pthread_mutex_trylock use_ast_mutex_trylock_instead_of_pthread_mutex_trylock
00559 #define pthread_mutex_init use_ast_mutex_init_instead_of_pthread_mutex_init
00560 #define pthread_mutex_destroy use_ast_mutex_destroy_instead_of_pthread_mutex_destroy
00561 #define pthread_cond_init use_ast_cond_init_instead_of_pthread_cond_init
00562 #define pthread_cond_destroy use_ast_cond_destroy_instead_of_pthread_cond_destroy
00563 #define pthread_cond_signal use_ast_cond_signal_instead_of_pthread_cond_signal
00564 #define pthread_cond_broadcast use_ast_cond_broadcast_instead_of_pthread_cond_broadcast
00565 #define pthread_cond_wait use_ast_cond_wait_instead_of_pthread_cond_wait
00566 #define pthread_cond_timedwait use_ast_cond_timedwait_instead_of_pthread_cond_timedwait
00567
00568 #define AST_MUTEX_INITIALIZER __use_AST_MUTEX_DEFINE_STATIC_rather_than_AST_MUTEX_INITIALIZER__
00569
00570 #define gethostbyname __gethostbyname__is__not__reentrant__use__ast_gethostbyname__instead__
00571
00572 #ifndef __linux__
00573 #define pthread_create __use_ast_pthread_create_instead__
00574 #endif
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586 int ast_atomic_fetchadd_int_slow(volatile int *p, int v);
00587
00588 #include "asterisk/inline_api.h"
00589
00590 #if defined(HAVE_OSX_ATOMICS)
00591 #include "libkern/OSAtomic.h"
00592 #endif
00593
00594
00595
00596
00597
00598
00599 #if defined(HAVE_GCC_ATOMICS)
00600 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
00601 {
00602 return __sync_fetch_and_add(p, v);
00603 })
00604 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 4)
00605 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
00606 {
00607 return OSAtomicAdd32(v, (int32_t *) p) - v;
00608 })
00609 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 8)
00610 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
00611 {
00612 return OSAtomicAdd64(v, (int64_t *) p) - v;
00613 #elif defined (__i386__) || defined(__x86_64__)
00614 #ifdef sun
00615 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
00616 {
00617 __asm __volatile (
00618 " lock; xaddl %0, %1 ; "
00619 : "+r" (v),
00620 "=m" (*p)
00621 : "m" (*p));
00622 return (v);
00623 })
00624 #else
00625 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
00626 {
00627 __asm __volatile (
00628 " lock xaddl %0, %1 ; "
00629 : "+r" (v),
00630 "=m" (*p)
00631 : "m" (*p));
00632 return (v);
00633 })
00634 #endif
00635 #else
00636 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
00637 {
00638 return ast_atomic_fetchadd_int_slow(p, v);
00639 })
00640 #endif
00641
00642
00643
00644
00645 #if defined(HAVE_GCC_ATOMICS)
00646 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
00647 {
00648 return __sync_sub_and_fetch(p, 1) == 0;
00649 })
00650 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 4)
00651 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
00652 {
00653 return OSAtomicAdd32( -1, (int32_t *) p) == 0;
00654 })
00655 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 8)
00656 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
00657 {
00658 return OSAtomicAdd64( -1, (int64_t *) p) == 0;
00659 #else
00660 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
00661 {
00662 int a = ast_atomic_fetchadd_int(p, -1);
00663 return a == 1;
00664 })
00665 #endif
00666
00667 #endif