From 2da6f7cebae5a224f1f982981103a15a2ecda59a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Mon, 3 Nov 2014 15:43:44 +0200 Subject: [PATCH] MDEV-7017: Add function to print semaphore waits Add function to print to stderr all current semaphore waits. This function should be able to executed inside a gdb/ddd. --- storage/innobase/include/sync0arr.h | 6 +++ storage/innobase/include/sync0sync.h | 5 +++ storage/innobase/sync/sync0arr.c | 65 +++++++++++++++++++++++++++- storage/innobase/sync/sync0sync.c | 10 +++++ storage/xtradb/include/sync0arr.h | 6 +++ storage/xtradb/include/sync0sync.h | 5 +++ storage/xtradb/sync/sync0arr.c | 64 ++++++++++++++++++++++++++- storage/xtradb/sync/sync0sync.c | 10 +++++ 8 files changed, 169 insertions(+), 2 deletions(-) diff --git a/storage/innobase/include/sync0arr.h b/storage/innobase/include/sync0arr.h index 4bce9435577..a31c61a3806 100644 --- a/storage/innobase/include/sync0arr.h +++ b/storage/innobase/include/sync0arr.h @@ -138,6 +138,12 @@ sync_array_print_info( sync_array_t* arr); /*!< in: wait array */ +/**********************************************************************//** +Prints info of the wait array without using any mutexes/semaphores. */ +UNIV_INTERN +void +sync_array_print_innodb(void); + #ifndef UNIV_NONINL #include "sync0arr.ic" #endif diff --git a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h index 9b07c4758c9..78f5b8dd02c 100644 --- a/storage/innobase/include/sync0sync.h +++ b/storage/innobase/include/sync0sync.h @@ -777,6 +777,11 @@ extern ut_list_base_node_t mutex_list; /** Mutex protecting the mutex_list variable */ extern mutex_t mutex_list_mutex; +/*******************************************************************//** +Get sync array */ +UNIV_INTERN +sync_array_t* +sync_array_get(void); #ifndef UNIV_NONINL #include "sync0sync.ic" diff --git a/storage/innobase/sync/sync0arr.c b/storage/innobase/sync/sync0arr.c index ba1d5cd8e61..5c4ba2058bd 100644 --- a/storage/innobase/sync/sync0arr.c +++ b/storage/innobase/sync/sync0arr.c @@ -2,7 +2,7 @@ Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. -Copyright (c) 2013, 2014, SkySQL Ab. All Rights Reserved. +Copyright (c) 2013, 2014, MariaDB Corporation. All Rights Reserved. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -1111,3 +1111,66 @@ sync_array_print_info( sync_array_exit(arr); } + +/**********************************************************************//** +Prints info of the wait array without using any mutexes/semaphores. */ +UNIV_INTERN +void +sync_array_print_innodb(void) +/*=========================*/ +{ + ulint i; + sync_array_t* arr = sync_array_get(); + + fputs("InnoDB: Semaphore wait debug output started for InnoDB:\n", stderr); + + for (i = 0; i < arr->n_cells; i++) { + void* wait_object; + sync_cell_t* cell; + os_thread_id_t reserver=(os_thread_id_t)ULINT_UNDEFINED; + ulint loop=0; + + cell = sync_array_get_nth_cell(arr, i); + + wait_object = cell->wait_object; + + if (wait_object == NULL || !cell->waiting) { + + continue; + } + + fputs("InnoDB: Warning: semaphore wait:\n", + stderr); + sync_array_cell_print(stderr, cell, &reserver); + + /* Try to output cell information for writer recursive way */ + while (reserver != (os_thread_id_t)ULINT_UNDEFINED) { + sync_cell_t* reserver_wait; + + reserver_wait = sync_array_find_thread(arr, reserver); + + if (reserver_wait && + reserver_wait->wait_object != NULL && + reserver_wait->waiting) { + fputs("InnoDB: Warning: Writer thread is waiting this semaphore:\n", + stderr); + sync_array_cell_print(stderr, reserver_wait, &reserver); + + if (reserver_wait->thread == reserver) { + reserver = (os_thread_id_t)ULINT_UNDEFINED; + } + } else { + reserver = (os_thread_id_t)ULINT_UNDEFINED; + } + + /* This is protection against loop */ + if (loop > 100) { + fputs("InnoDB: Warning: Too many waiting threads.\n", stderr); + break; + } + } + } + + fputs("InnoDB: Semaphore wait debug output ended:\n", stderr); + +} diff --git a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c index 3ae77616faf..03cc3e46f3c 100644 --- a/storage/innobase/sync/sync0sync.c +++ b/storage/innobase/sync/sync0sync.c @@ -1665,3 +1665,13 @@ sync_print( sync_print_wait_info(file); } + +/*******************************************************************//** +Get sync array */ +UNIV_INTERN +sync_array_t* +sync_array_get(void) +/*================*/ +{ + return sync_primary_wait_array; +} diff --git a/storage/xtradb/include/sync0arr.h b/storage/xtradb/include/sync0arr.h index 4bce9435577..5fb0330aa10 100644 --- a/storage/xtradb/include/sync0arr.h +++ b/storage/xtradb/include/sync0arr.h @@ -138,6 +138,12 @@ sync_array_print_info( sync_array_t* arr); /*!< in: wait array */ +/**********************************************************************//** +Prints info of the wait array without using any mutexes/semaphores. */ +UNIV_INTERN +void +sync_array_print_xtradb(void); + #ifndef UNIV_NONINL #include "sync0arr.ic" #endif diff --git a/storage/xtradb/include/sync0sync.h b/storage/xtradb/include/sync0sync.h index b3b99b10630..8509058ab1f 100644 --- a/storage/xtradb/include/sync0sync.h +++ b/storage/xtradb/include/sync0sync.h @@ -793,6 +793,11 @@ extern ut_list_base_node_t mutex_list; /** Mutex protecting the mutex_list variable */ extern mutex_t mutex_list_mutex; +/*******************************************************************//** +Get sync array */ +UNIV_INTERN +sync_array_t* +sync_array_get(void); #ifndef UNIV_NONINL #include "sync0sync.ic" diff --git a/storage/xtradb/sync/sync0arr.c b/storage/xtradb/sync/sync0arr.c index 503cc38d0da..73cd6ea1739 100644 --- a/storage/xtradb/sync/sync0arr.c +++ b/storage/xtradb/sync/sync0arr.c @@ -2,7 +2,7 @@ Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. -Copyright (c) 2013, 2014, SkySQL Ab. All Rights Reserved. +Copyright (c) 2013, 2014, MariaDB Corporation. All Rights Reserved. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -1147,3 +1147,65 @@ sync_array_print_info( sync_array_exit(arr); } + +/**********************************************************************//** +Prints info of the wait array without using any mutexes/semaphores. */ +UNIV_INTERN +void +sync_array_print_xtradb(void) +/*=========================*/ +{ + ulint i; + sync_array_t* arr = sync_array_get(); + + fputs("InnoDB: Semaphore wait debug output started for XtraDB:\n", stderr); + + for (i = 0; i < arr->n_cells; i++) { + void* wait_object; + sync_cell_t* cell; + os_thread_id_t reserver=(os_thread_id_t)ULINT_UNDEFINED; + ulint loop=0; + + cell = sync_array_get_nth_cell(arr, i); + + wait_object = cell->wait_object; + + if (wait_object == NULL || !cell->waiting) { + + continue; + } + + fputs("InnoDB: Warning: semaphore wait:\n", + stderr); + sync_array_cell_print(stderr, cell, &reserver); + + /* Try to output cell information for writer recursive way */ + while (reserver != (os_thread_id_t)ULINT_UNDEFINED) { + sync_cell_t* reserver_wait; + + reserver_wait = sync_array_find_thread(arr, reserver); + + if (reserver_wait && + reserver_wait->wait_object != NULL && + reserver_wait->waiting) { + fputs("InnoDB: Warning: Writer thread is waiting this semaphore:\n", + stderr); + sync_array_cell_print(stderr, reserver_wait, &reserver); + + if (reserver_wait->thread == reserver) { + reserver = (os_thread_id_t)ULINT_UNDEFINED; + } + } else { + reserver = (os_thread_id_t)ULINT_UNDEFINED; + } + + /* This is protection against loop */ + if (loop > 100) { + fputs("InnoDB: Warning: Too many waiting threads.\n", stderr); + break; + } + } + } + + fputs("InnoDB: Semaphore wait debug output ended:\n", stderr); +} diff --git a/storage/xtradb/sync/sync0sync.c b/storage/xtradb/sync/sync0sync.c index 42803cdd20b..906a1d9b893 100644 --- a/storage/xtradb/sync/sync0sync.c +++ b/storage/xtradb/sync/sync0sync.c @@ -1644,3 +1644,13 @@ sync_print( sync_print_wait_info(file); } + +/*******************************************************************//** +Get sync array */ +UNIV_INTERN +sync_array_t* +sync_array_get(void) +/*================*/ +{ + return sync_primary_wait_array; +}