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 { AST_LOCK_TRACK_INIT_VALUE, 1, PTHREAD_MUTEX_INIT_VALUE }
00095 #define AST_MUTEX_INIT_VALUE_NOTRACKING { AST_LOCK_TRACK_INIT_VALUE, 0, PTHREAD_MUTEX_INIT_VALUE }
00096
00097 #define AST_RWLOCK_INIT_VALUE { AST_LOCK_TRACK_INIT_VALUE, 1, __AST_RWLOCK_INIT_VALUE }
00098 #define AST_RWLOCK_INIT_VALUE_NOTRACKING { AST_LOCK_TRACK_INIT_VALUE, 0, __AST_RWLOCK_INIT_VALUE }
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
00123 struct ast_lock_track track;
00124 unsigned int tracking:1;
00125 pthread_mutex_t mutex;
00126 };
00127
00128
00129
00130
00131
00132
00133 struct ast_rwlock_info {
00134
00135 struct ast_lock_track track;
00136 unsigned int tracking:1;
00137 pthread_rwlock_t lock;
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(ast_rwlock_t *t, const char *name, const char *filename, int line, const char *func);
00178 int __ast_rwlock_rdlock(ast_rwlock_t *t, const char *name, const char *filename, int line, const char *func);
00179 int __ast_rwlock_wrlock(ast_rwlock_t *t, const char *name, const char *filename, int line, const char *func);
00180 int __ast_rwlock_timedrdlock(ast_rwlock_t *t, const char *name, const struct timespec *abs_timeout, const char *filename, int line, const char *func);
00181 int __ast_rwlock_timedwrlock(ast_rwlock_t *t, const char *name, const struct timespec *abs_timeout, const char *filename, int line, const char *func);
00182 int __ast_rwlock_tryrdlock(ast_rwlock_t *t, const char *name, const char *filename, int line, const char *func);
00183 int __ast_rwlock_trywrlock(ast_rwlock_t *t, const char *name, const char *filename, int line, const char *func);
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(a, #a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
00201 #define ast_rwlock_rdlock(a) __ast_rwlock_rdlock(a, #a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
00202 #define ast_rwlock_wrlock(a) __ast_rwlock_wrlock(a, #a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
00203 #define ast_rwlock_tryrdlock(a) __ast_rwlock_tryrdlock(a, #a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
00204 #define ast_rwlock_trywrlock(a) __ast_rwlock_trywrlock(a, #a, __FILE__, __LINE__, __PRETTY_FUNCTION__)
00205 #define ast_rwlock_timedrdlock(a, b) __ast_rwlock_timedrdlock(a, #a, b, __FILE__, __LINE__, __PRETTY_FUNCTION__)
00206 #define ast_rwlock_timedwrlock(a, b) __ast_rwlock_timedwrlock(a, #a, b, __FILE__, __LINE__, __PRETTY_FUNCTION__)
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 #else
00285 #ifdef HAVE_BKTR
00286 #define ast_remove_lock_info(ignore,me)
00287 #else
00288 #define ast_remove_lock_info(ignore)
00289 #endif
00290 #endif
00291
00292 #ifdef HAVE_BKTR
00293 static inline void __dump_backtrace(struct ast_bt *bt, int canlog)
00294 {
00295 char **strings;
00296
00297 ssize_t i;
00298
00299 strings = backtrace_symbols(bt->addresses, bt->num_frames);
00300
00301 for (i = 0; i < bt->num_frames; i++)
00302 __ast_mutex_logger("%s\n", strings[i]);
00303
00304 free(strings);
00305 }
00306 #endif
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 void log_show_lock(void *this_lock_addr);
00319
00320
00321
00322
00323
00324
00325
00326 #if !defined(LOW_MEMORY)
00327 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);
00328 #else
00329 #define ast_find_lock_info(a,b,c,d,e,f,g,h) -1
00330 #endif
00331
00332
00333
00334
00335
00336
00337
00338 #define CHANNEL_DEADLOCK_AVOIDANCE(chan) \
00339 do { \
00340 char __filename[80], __func[80], __mutex_name[80]; \
00341 int __lineno; \
00342 int __res = ast_find_lock_info(ao2_object_get_lockaddr(chan), __filename, sizeof(__filename), &__lineno, __func, sizeof(__func), __mutex_name, sizeof(__mutex_name)); \
00343 int __res2 = ast_channel_unlock(chan); \
00344 usleep(1); \
00345 if (__res < 0) { \
00346 if (__res2) { \
00347 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)); \
00348 } else { \
00349 ast_channel_lock(chan); \
00350 } \
00351 } else { \
00352 if (__res2) { \
00353 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); \
00354 } else { \
00355 __ao2_lock(chan, __filename, __func, __lineno, __mutex_name); \
00356 } \
00357 } \
00358 } while (0)
00359
00360 #define DEADLOCK_AVOIDANCE(lock) \
00361 do { \
00362 char __filename[80], __func[80], __mutex_name[80]; \
00363 int __lineno; \
00364 int __res = ast_find_lock_info(lock, __filename, sizeof(__filename), &__lineno, __func, sizeof(__func), __mutex_name, sizeof(__mutex_name)); \
00365 int __res2 = ast_mutex_unlock(lock); \
00366 usleep(1); \
00367 if (__res < 0) { \
00368 if (__res2 == 0) { \
00369 ast_mutex_lock(lock); \
00370 } else { \
00371 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)); \
00372 } \
00373 } else { \
00374 if (__res2 == 0) { \
00375 __ast_pthread_mutex_lock(__filename, __lineno, __func, __mutex_name, lock); \
00376 } else { \
00377 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); \
00378 } \
00379 } \
00380 } while (0)
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394 #define DLA_UNLOCK(lock) \
00395 do { \
00396 char __filename[80], __func[80], __mutex_name[80]; \
00397 int __lineno; \
00398 int __res = ast_find_lock_info(lock, __filename, sizeof(__filename), &__lineno, __func, sizeof(__func), __mutex_name, sizeof(__mutex_name)); \
00399 int __res2 = ast_mutex_unlock(lock);
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 #define DLA_LOCK(lock) \
00414 if (__res < 0) { \
00415 if (__res2) { \
00416 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)); \
00417 } else { \
00418 ast_mutex_lock(lock); \
00419 } \
00420 } else { \
00421 if (__res2) { \
00422 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); \
00423 } else { \
00424 __ast_pthread_mutex_lock(__filename, __lineno, __func, __mutex_name, lock); \
00425 } \
00426 } \
00427 } while (0)
00428
00429 static inline void ast_reentrancy_lock(struct ast_lock_track *lt)
00430 {
00431 pthread_mutex_lock(<->reentr_mutex);
00432 }
00433
00434 static inline void ast_reentrancy_unlock(struct ast_lock_track *lt)
00435 {
00436 pthread_mutex_unlock(<->reentr_mutex);
00437 }
00438
00439 static inline void ast_reentrancy_init(struct ast_lock_track *lt)
00440 {
00441 int i;
00442 pthread_mutexattr_t reentr_attr;
00443
00444 for (i = 0; i < AST_MAX_REENTRANCY; i++) {
00445 lt->file[i] = NULL;
00446 lt->lineno[i] = 0;
00447 lt->func[i] = NULL;
00448 lt->thread[i] = 0;
00449 #ifdef HAVE_BKTR
00450 memset(<->backtrace[i], 0, sizeof(lt->backtrace[i]));
00451 #endif
00452 }
00453
00454 lt->reentrancy = 0;
00455
00456 pthread_mutexattr_init(&reentr_attr);
00457 pthread_mutexattr_settype(&reentr_attr, AST_MUTEX_KIND);
00458 pthread_mutex_init(<->reentr_mutex, &reentr_attr);
00459 pthread_mutexattr_destroy(&reentr_attr);
00460 }
00461
00462 static inline void delete_reentrancy_cs(struct ast_lock_track *lt)
00463 {
00464 pthread_mutex_destroy(<->reentr_mutex);
00465 }
00466
00467 #else
00468
00469 #define CHANNEL_DEADLOCK_AVOIDANCE(chan) \
00470 ast_channel_unlock(chan); \
00471 usleep(1); \
00472 ast_channel_lock(chan);
00473
00474 #define DEADLOCK_AVOIDANCE(lock) \
00475 do { \
00476 int __res; \
00477 if (!(__res = ast_mutex_unlock(lock))) { \
00478 usleep(1); \
00479 ast_mutex_lock(lock); \
00480 } else { \
00481 ast_log(LOG_WARNING, "Failed to unlock mutex '%s' (%s). I will NOT try to relock. {{{ THIS IS A BUG. }}}\n", #lock, strerror(__res)); \
00482 } \
00483 } while (0)
00484
00485 #define DLA_UNLOCK(lock) ast_mutex_unlock(lock)
00486
00487 #define DLA_LOCK(lock) ast_mutex_lock(lock)
00488
00489 #endif
00490
00491 #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS)
00492
00493
00494
00495
00496 #define __AST_MUTEX_DEFINE(scope, mutex, init_val, track) \
00497 scope ast_mutex_t mutex = init_val; \
00498 static void __attribute__((constructor)) init_##mutex(void) \
00499 { \
00500 if (track) \
00501 ast_mutex_init(&mutex); \
00502 else \
00503 ast_mutex_init_notracking(&mutex); \
00504 } \
00505 \
00506 static void __attribute__((destructor)) fini_##mutex(void) \
00507 { \
00508 ast_mutex_destroy(&mutex); \
00509 }
00510 #else
00511
00512 #define __AST_MUTEX_DEFINE(scope, mutex, init_val, track) scope ast_mutex_t mutex = init_val
00513 #endif
00514
00515 #define AST_MUTEX_DEFINE_STATIC(mutex) __AST_MUTEX_DEFINE(static, mutex, AST_MUTEX_INIT_VALUE, 1)
00516 #define AST_MUTEX_DEFINE_STATIC_NOTRACKING(mutex) __AST_MUTEX_DEFINE(static, mutex, AST_MUTEX_INIT_VALUE_NOTRACKING, 0)
00517
00518
00519
00520 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
00521 #define __AST_RWLOCK_DEFINE(scope, rwlock, init_val, track) \
00522 scope ast_rwlock_t rwlock = init_val; \
00523 static void __attribute__((constructor)) init_##rwlock(void) \
00524 { \
00525 if (track) \
00526 ast_rwlock_init(&rwlock); \
00527 else \
00528 ast_rwlock_init_notracking(&rwlock); \
00529 } \
00530 static void __attribute__((destructor)) fini_##rwlock(void) \
00531 { \
00532 ast_rwlock_destroy(&rwlock); \
00533 }
00534 #else
00535 #define __AST_RWLOCK_DEFINE(scope, rwlock, init_val, track) scope ast_rwlock_t rwlock = init_val
00536 #endif
00537
00538 #define AST_RWLOCK_DEFINE_STATIC(rwlock) __AST_RWLOCK_DEFINE(static, rwlock, AST_RWLOCK_INIT_VALUE, 1)
00539 #define AST_RWLOCK_DEFINE_STATIC_NOTRACKING(rwlock) __AST_RWLOCK_DEFINE(static, rwlock, AST_RWLOCK_INIT_VALUE_NOTRACKING, 0)
00540
00541 #ifndef __CYGWIN__
00542 #define pthread_mutex_t use_ast_mutex_t_instead_of_pthread_mutex_t
00543 #define pthread_cond_t use_ast_cond_t_instead_of_pthread_cond_t
00544 #endif
00545 #define pthread_mutex_lock use_ast_mutex_lock_instead_of_pthread_mutex_lock
00546 #define pthread_mutex_unlock use_ast_mutex_unlock_instead_of_pthread_mutex_unlock
00547 #define pthread_mutex_trylock use_ast_mutex_trylock_instead_of_pthread_mutex_trylock
00548 #define pthread_mutex_init use_ast_mutex_init_instead_of_pthread_mutex_init
00549 #define pthread_mutex_destroy use_ast_mutex_destroy_instead_of_pthread_mutex_destroy
00550 #define pthread_cond_init use_ast_cond_init_instead_of_pthread_cond_init
00551 #define pthread_cond_destroy use_ast_cond_destroy_instead_of_pthread_cond_destroy
00552 #define pthread_cond_signal use_ast_cond_signal_instead_of_pthread_cond_signal
00553 #define pthread_cond_broadcast use_ast_cond_broadcast_instead_of_pthread_cond_broadcast
00554 #define pthread_cond_wait use_ast_cond_wait_instead_of_pthread_cond_wait
00555 #define pthread_cond_timedwait use_ast_cond_timedwait_instead_of_pthread_cond_timedwait
00556
00557 #define AST_MUTEX_INITIALIZER __use_AST_MUTEX_DEFINE_STATIC_rather_than_AST_MUTEX_INITIALIZER__
00558
00559 #define gethostbyname __gethostbyname__is__not__reentrant__use__ast_gethostbyname__instead__
00560
00561 #ifndef __linux__
00562 #define pthread_create __use_ast_pthread_create_instead__
00563 #endif
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575 int ast_atomic_fetchadd_int_slow(volatile int *p, int v);
00576
00577 #include "asterisk/inline_api.h"
00578
00579 #if defined(HAVE_OSX_ATOMICS)
00580 #include "libkern/OSAtomic.h"
00581 #endif
00582
00583
00584
00585
00586
00587
00588 #if defined(HAVE_GCC_ATOMICS)
00589 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
00590 {
00591 return __sync_fetch_and_add(p, v);
00592 })
00593 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 4)
00594 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
00595 {
00596 return OSAtomicAdd32(v, (int32_t *) p) - v;
00597 })
00598 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 8)
00599 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
00600 {
00601 return OSAtomicAdd64(v, (int64_t *) p) - v;
00602 #elif defined (__i386__) || defined(__x86_64__)
00603 #ifdef sun
00604 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
00605 {
00606 __asm __volatile (
00607 " lock; xaddl %0, %1 ; "
00608 : "+r" (v),
00609 "=m" (*p)
00610 : "m" (*p));
00611 return (v);
00612 })
00613 #else
00614 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
00615 {
00616 __asm __volatile (
00617 " lock xaddl %0, %1 ; "
00618 : "+r" (v),
00619 "=m" (*p)
00620 : "m" (*p));
00621 return (v);
00622 })
00623 #endif
00624 #else
00625 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
00626 {
00627 return ast_atomic_fetchadd_int_slow(p, v);
00628 })
00629 #endif
00630
00631
00632
00633
00634 #if defined(HAVE_GCC_ATOMICS)
00635 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
00636 {
00637 return __sync_sub_and_fetch(p, 1) == 0;
00638 })
00639 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 4)
00640 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
00641 {
00642 return OSAtomicAdd32( -1, (int32_t *) p) == 0;
00643 })
00644 #elif defined(HAVE_OSX_ATOMICS) && (SIZEOF_INT == 8)
00645 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
00646 {
00647 return OSAtomicAdd64( -1, (int64_t *) p) == 0;
00648 #else
00649 AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
00650 {
00651 int a = ast_atomic_fetchadd_int(p, -1);
00652 return a == 1;
00653 })
00654 #endif
00655
00656 #endif