35 #include "sync0arr.ic"
143 static ulint sync_array_size;
150 static ulint sg_count;
152 #ifdef UNIV_SYNC_DEBUG
159 sync_array_detect_deadlock(
173 sync_array_get_nth_cell(
179 ut_a(n < arr->n_cells);
181 return(arr->
array + n);
225 memset(arr, 0x0,
sizeof(*arr));
229 memset(arr->
array, 0x0, sz);
272 sync_array_enter(arr);
274 for (i = 0; i < arr->
n_cells; i++) {
275 cell = sync_array_get_nth_cell(arr, i);
283 sync_array_exit(arr);
296 if (type == SYNC_MUTEX) {
298 }
else if (type == RW_LOCK_WAIT_EX) {
326 sync_array_enter(arr);
331 for (i = 0; i < arr->
n_cells; i++) {
332 cell = sync_array_get_nth_cell(arr, i);
339 if (type == SYNC_MUTEX) {
356 sync_array_exit(arr);
361 event = sync_cell_get_event(cell);
394 sync_array_enter(arr);
396 cell = sync_array_get_nth_cell(arr, index);
402 event = sync_cell_get_event(cell);
405 #ifdef UNIV_SYNC_DEBUG
412 rw_lock_debug_mutex_enter();
414 if (TRUE == sync_array_detect_deadlock(arr, cell, cell, 0)) {
416 fputs(
"########################################\n", stderr);
420 rw_lock_debug_mutex_exit();
422 sync_array_exit(arr);
433 sync_array_cell_print(
446 "--Thread %lu has waited at %s line %lu"
447 " for %.2f seconds the semaphore:\n",
452 if (type == SYNC_MUTEX) {
458 "Mutex at %p created file %s line %lu, lock var %lu\n"
459 #ifdef UNIV_SYNC_DEBUG
460 "Last time reserved in file %s line %lu, "
462 "waiters flag %lu\n",
464 (ulong) mutex->
cline,
466 #ifdef UNIV_SYNC_DEBUG
467 mutex->file_name, (ulong) mutex->line,
471 }
else if (type == RW_LOCK_EX
472 || type == RW_LOCK_WAIT_EX
473 || type == RW_LOCK_SHARED) {
475 fputs(type == RW_LOCK_EX ?
"X-lock on"
476 : type == RW_LOCK_WAIT_EX ?
"X-lock (wait_ex) on"
477 :
"S-lock on", file);
482 " RW-latch at %p created in file %s line %lu\n",
484 (ulong) rwlock->
cline);
486 if (writer != RW_LOCK_NOT_LOCKED) {
488 "a writer (thread id %lu) has"
489 " reserved it in mode %s",
493 :
" wait exclusive\n");
497 "number of readers %lu, waiters flag %lu, "
499 "Last time read locked in file %s line %lu\n"
500 "Last time write locked in file %s line %lu\n",
513 fputs(
"wait has ended\n", file);
517 #ifdef UNIV_SYNC_DEBUG
523 sync_array_find_thread(
531 for (i = 0; i < arr->
n_cells; i++) {
533 cell = sync_array_get_nth_cell(arr, i);
550 sync_array_deadlock_step(
570 new_cell = sync_array_find_thread(arr, thread);
572 if (new_cell == start) {
574 fputs(
"########################################\n"
575 "DEADLOCK of threads detected!\n", stderr);
579 }
else if (new_cell) {
580 return(sync_array_detect_deadlock(
581 arr, start, new_cell, depth + 1));
592 sync_array_detect_deadlock(
604 rw_lock_debug_t*debug;
626 thread = mutex->thread_id;
636 ret = sync_array_deadlock_step(arr, start, thread, 0,
640 "Mutex %p owned by thread %lu file %s line %lu\n",
642 mutex->file_name, (ulong) mutex->line);
643 sync_array_cell_print(stderr, cell);
660 thread = debug->thread_id;
662 if (((debug->lock_type == RW_LOCK_EX)
664 || ((debug->lock_type == RW_LOCK_WAIT_EX)
666 || (debug->lock_type == RW_LOCK_SHARED)) {
674 ret = sync_array_deadlock_step(
675 arr, start, thread, debug->pass,
679 fprintf(stderr,
"rw-lock %p ",
681 sync_array_cell_print(stderr, cell);
682 rw_lock_debug_print(stderr, debug);
698 thread = debug->thread_id;
700 if ((debug->lock_type == RW_LOCK_EX)
701 || (debug->lock_type == RW_LOCK_WAIT_EX)) {
708 ret = sync_array_deadlock_step(
709 arr, start, thread, debug->pass,
732 sync_arr_cell_can_wake_up(
792 sync_array_enter(arr);
794 cell = sync_array_get_nth_cell(arr, index);
805 sync_array_exit(arr);
815 #ifdef HAVE_ATOMIC_BUILTINS
816 (void) os_atomic_increment_ulint(&sg_count, 1);
832 sync_array_wake_threads_if_sema_free_low(
839 sync_array_enter(arr);
844 cell = sync_array_get_nth_cell(arr, i);
850 if (sync_arr_cell_can_wake_up(cell)) {
853 event = sync_cell_get_event(cell);
860 sync_array_exit(arr);
878 for (i = 0; i < sync_array_size; ++
i) {
880 sync_array_wake_threads_if_sema_free_low(
890 sync_array_print_long_waits_low(
898 ulint fatal_timeout = srv_fatal_semaphore_wait_threshold;
900 double longest_diff = 0;
903 if (fatal_timeout > SRV_SEMAPHORE_WAIT_EXTENSION) {
907 #ifdef UNIV_DEBUG_VALGRIND
913 # define SYNC_ARRAY_TIMEOUT 2400
916 # define SYNC_ARRAY_TIMEOUT 240
919 for (i = 0; i < arr->
n_cells; i++) {
925 cell = sync_array_get_nth_cell(arr, i);
929 if (wait_object == NULL || !cell->
waiting) {
936 if (diff > SYNC_ARRAY_TIMEOUT) {
937 fputs(
"InnoDB: Warning: a long semaphore wait:\n",
939 sync_array_cell_print(stderr, cell);
943 if (diff > fatal_timeout) {
947 if (diff > longest_diff) {
954 #undef SYNC_ARRAY_TIMEOUT
971 ibool noticed = FALSE;
973 for (i = 0; i < sync_array_size; ++
i) {
977 sync_array_enter(arr);
979 if (sync_array_print_long_waits_low(
980 arr, waiter, sema, ¬iced)) {
985 sync_array_exit(arr);
992 "InnoDB: ###### Starts InnoDB Monitor"
993 " for 30 secs to print diagnostic info:\n");
995 old_val = srv_print_innodb_monitor;
1004 "InnoDB: Pending preads %lu, pwrites %lu\n",
1008 srv_print_innodb_monitor = TRUE;
1013 srv_print_innodb_monitor = old_val;
1015 "InnoDB: ###### Diagnostic info printed"
1016 " to the standard error stream\n");
1026 sync_array_print_info_low(
1035 "OS WAIT ARRAY INFO: reservation count %ld\n",
1041 cell = sync_array_get_nth_cell(arr, i);
1045 sync_array_cell_print(file, cell);
1054 sync_array_print_info(
1059 sync_array_enter(arr);
1061 sync_array_print_info_low(file, arr);
1063 sync_array_exit(arr);
1078 ut_a(sync_wait_array == NULL);
1089 ut_malloc(
sizeof(*sync_wait_array) * sync_array_size));
1091 n_slots = 1 + (n_threads - 1) / sync_array_size;
1093 for (i = 0; i < sync_array_size; ++
i) {
1095 sync_wait_array[
i] = sync_array_create(n_slots);
1108 for (i = 0; i < sync_array_size; ++
i) {
1109 sync_array_free(sync_wait_array[i]);
1113 sync_wait_array = NULL;
1126 for (i = 0; i < sync_array_size; ++
i) {
1127 sync_array_print_info(file, sync_wait_array[i]);
1131 "OS WAIT ARRAY INFO: signal count %ld\n", (
long) sg_count);
1145 #ifdef HAVE_ATOMIC_BUILTINS
1146 i = os_atomic_increment_ulint(&count, 1);
1151 return(sync_wait_array[i % sync_array_size]);