35 #include "sync0arr.ic"
142 #ifdef UNIV_PFS_MUTEX
144 UNIV_INTERN mysql_pfs_key_t syn_arr_mutex_key;
147 #ifdef UNIV_SYNC_DEBUG
154 sync_array_detect_deadlock(
168 sync_array_get_nth_cell(
174 ut_a(n < arr->n_cells);
176 return(arr->
array + n);
194 mutex_enter(&(arr->
mutex));
215 mutex_exit(&(arr->
mutex));
243 memset(arr, 0x0,
sizeof(*arr));
247 memset(arr->
array, 0x0, sz);
256 mutex_create(syn_arr_mutex_key,
257 &arr->
mutex, SYNC_NO_ORDER_CHECK);
286 mutex_free(&(arr->
mutex));
308 sync_array_enter(arr);
310 for (i = 0; i < arr->
n_cells; i++) {
311 cell = sync_array_get_nth_cell(arr, i);
319 sync_array_exit(arr);
332 if (type == SYNC_MUTEX) {
334 }
else if (type == RW_LOCK_WAIT_EX) {
362 sync_array_enter(arr);
367 for (i = 0; i < arr->
n_cells; i++) {
368 cell = sync_array_get_nth_cell(arr, i);
375 if (type == SYNC_MUTEX) {
390 sync_array_exit(arr);
395 event = sync_cell_get_event(cell);
428 sync_array_enter(arr);
430 cell = sync_array_get_nth_cell(arr, index);
436 event = sync_cell_get_event(cell);
439 #ifdef UNIV_SYNC_DEBUG
446 rw_lock_debug_mutex_enter();
448 if (TRUE == sync_array_detect_deadlock(arr, cell, cell, 0)) {
450 fputs(
"########################################\n", stderr);
454 rw_lock_debug_mutex_exit();
456 sync_array_exit(arr);
467 sync_array_cell_print(
480 "--Thread %lu has waited at %s line %lu"
481 " for %.2f seconds the semaphore:\n",
486 if (type == SYNC_MUTEX) {
492 "Mutex at %p created file %s line %lu, lock var %lu\n"
493 #ifdef UNIV_SYNC_DEBUG
494 "Last time reserved in file %s line %lu, "
496 "waiters flag %lu\n",
498 (ulong) mutex->
cline,
500 #ifdef UNIV_SYNC_DEBUG
501 mutex->file_name, (ulong) mutex->line,
505 }
else if (type == RW_LOCK_EX
506 || type == RW_LOCK_WAIT_EX
507 || type == RW_LOCK_SHARED) {
509 fputs(type == RW_LOCK_EX ?
"X-lock on"
510 : type == RW_LOCK_WAIT_EX ?
"X-lock (wait_ex) on"
511 :
"S-lock on", file);
516 " RW-latch at %p created in file %s line %lu\n",
518 (ulong) rwlock->
cline);
520 if (writer != RW_LOCK_NOT_LOCKED) {
522 "a writer (thread id %lu) has"
523 " reserved it in mode %s",
527 :
" wait exclusive\n");
531 "number of readers %lu, waiters flag %lu, "
533 "Last time read locked in file %s line %lu\n"
534 "Last time write locked in file %s line %lu\n",
547 fputs(
"wait has ended\n", file);
551 #ifdef UNIV_SYNC_DEBUG
557 sync_array_find_thread(
565 for (i = 0; i < arr->
n_cells; i++) {
567 cell = sync_array_get_nth_cell(arr, i);
584 sync_array_deadlock_step(
604 new = sync_array_find_thread(arr, thread);
606 if (UNIV_UNLIKELY(
new == start)) {
612 fputs(
"########################################\n"
613 "DEADLOCK of threads detected!\n", stderr);
618 return(sync_array_detect_deadlock(arr, start,
new, depth + 1));
629 sync_array_detect_deadlock(
641 rw_lock_debug_t*debug;
663 thread = mutex->thread_id;
673 ret = sync_array_deadlock_step(arr, start, thread, 0,
677 "Mutex %p owned by thread %lu file %s line %lu\n",
679 mutex->file_name, (ulong) mutex->line);
680 sync_array_cell_print(stderr, cell);
695 while (debug != NULL) {
697 thread = debug->thread_id;
699 if (((debug->lock_type == RW_LOCK_EX)
701 || ((debug->lock_type == RW_LOCK_WAIT_EX)
703 || (debug->lock_type == RW_LOCK_SHARED)) {
711 ret = sync_array_deadlock_step(
712 arr, start, thread, debug->pass,
716 fprintf(stderr,
"rw-lock %p ",
718 sync_array_cell_print(stderr, cell);
719 rw_lock_debug_print(stderr, debug);
734 while (debug != NULL) {
736 thread = debug->thread_id;
738 if ((debug->lock_type == RW_LOCK_EX)
739 || (debug->lock_type == RW_LOCK_WAIT_EX)) {
746 ret = sync_array_deadlock_step(
747 arr, start, thread, debug->pass,
772 sync_arr_cell_can_wake_up(
832 sync_array_enter(arr);
834 cell = sync_array_get_nth_cell(arr, index);
845 sync_array_exit(arr);
856 #ifdef HAVE_ATOMIC_BUILTINS
857 (void) os_atomic_increment_ulint(&arr->
sg_count, 1);
859 sync_array_enter(arr);
863 sync_array_exit(arr);
886 sync_array_enter(arr);
891 while (count < arr->n_reserved) {
893 cell = sync_array_get_nth_cell(arr, i);
901 if (sync_arr_cell_can_wake_up(cell)) {
903 event = sync_cell_get_event(cell);
910 sync_array_exit(arr);
925 ibool noticed = FALSE;
927 ulint fatal_timeout = srv_fatal_semaphore_wait_threshold;
929 double longest_diff = 0;
931 #ifdef UNIV_DEBUG_VALGRIND
937 # define SYNC_ARRAY_TIMEOUT 2400
940 # define SYNC_ARRAY_TIMEOUT 240
952 if (wait_object == NULL || !cell->
waiting) {
959 if (diff > SYNC_ARRAY_TIMEOUT) {
960 fputs(
"InnoDB: Warning: a long semaphore wait:\n",
962 sync_array_cell_print(stderr, cell);
966 if (diff > fatal_timeout) {
970 if (diff > longest_diff) {
979 "InnoDB: ###### Starts InnoDB Monitor"
980 " for 30 secs to print diagnostic info:\n");
981 old_val = srv_print_innodb_monitor;
990 "InnoDB: Pending preads %lu, pwrites %lu\n",
994 srv_print_innodb_monitor = TRUE;
999 srv_print_innodb_monitor = old_val;
1001 "InnoDB: ###### Diagnostic info printed"
1002 " to the standard error stream\n");
1005 #undef SYNC_ARRAY_TIMEOUT
1014 sync_array_output_info(
1025 "OS WAIT ARRAY INFO: reservation count %ld, signal count %ld\n",
1030 while (count < arr->n_reserved) {
1032 cell = sync_array_get_nth_cell(arr, i);
1036 sync_array_cell_print(file, cell);
1052 sync_array_enter(arr);
1054 sync_array_output_info(file, arr);
1056 sync_array_exit(arr);
UNIV_INTERN void sync_array_validate(sync_array_t *arr)
#define UT_LIST_GET_NEXT(NAME, N)
ulint os_file_n_pending_pwrites
ulint os_file_n_pending_preads
UNIV_INTERN void os_mutex_free(os_mutex_t mutex)
UNIV_INTERN void * ut_malloc(ulint n)
sync_array_t * sync_primary_wait_array
UNIV_INTERN void sync_arr_wake_threads_if_sema_free(void)
UNIV_INTERN void os_mutex_enter(os_mutex_t mutex)
ibool ut_dbg_stop_threads
const char * last_x_file_name
UNIV_INLINE ulint rw_lock_get_writer(const rw_lock_t *lock)
volatile os_thread_id_t writer_thread
rw_lock_t * old_wait_rw_lock
#define SYNC_ARRAY_OS_MUTEX
UNIV_INLINE lock_word_t mutex_get_lock_word(const mutex_t *mutex)
const char * innobase_basename(const char *path_name)
UNIV_INTERN void sync_array_wait_event(sync_array_t *arr, ulint index)
const char * last_s_file_name
UNIV_INTERN void os_mutex_exit(os_mutex_t mutex)
UNIV_INTERN void os_event_set(os_event_t event)
UNIV_INTERN void os_thread_sleep(ulint tm)
UNIV_INTERN ib_int64_t os_event_reset(os_event_t event)
UNIV_INTERN sync_array_t * sync_array_create(ulint n_cells, ulint protection)
#define UT_LIST_GET_FIRST(BASE)
UNIV_INTERN os_mutex_t os_mutex_create(void)
UNIV_INLINE ulint rw_lock_get_reader_count(const rw_lock_t *lock)
UNIV_INTERN ibool sync_array_print_long_waits(os_thread_id_t *waiter, const void **sema) __attribute__((nonnull))
UNIV_INTERN void sync_array_free_cell(sync_array_t *arr, ulint index)
os_thread_t os_thread_id_t
UNIV_INTERN void ut_free(void *ptr)
UNIV_INTERN void sync_array_free(sync_array_t *arr)
volatile lock_word_t lock_word
UNIV_INTERN void sync_array_reserve_cell(sync_array_t *arr, void *object, ulint type, const char *file, ulint line, ulint *index)
UNIV_INTERN os_thread_id_t os_thread_get_curr_id(void)
UNIV_INTERN void sync_array_object_signalled(sync_array_t *arr)
UNIV_INTERN void sync_array_print_info(FILE *file, sync_array_t *arr)
UNIV_INTERN void os_event_wait_low(os_event_t event, ib_int64_t reset_sig_count)
struct sync_cell_struct sync_cell_t
UNIV_INTERN ulint os_thread_pf(os_thread_id_t a)
UNIV_INTERN ibool os_thread_eq(os_thread_id_t a, os_thread_id_t b)