Commit 05a583aa authored by marko's avatar marko

Port r1034 from branches/zip: Remove some instrumentation and reduce

the output of SHOW MUTEX STATUS in non-debug builds.  (Bug #24386)
parent 647f798c
......@@ -18,16 +18,18 @@ Creates a hash table with >= n array cells. The actual number of cells is
chosen to be a prime number slightly bigger than n. */
hash_table_t*
ha_create(
/*======*/
ha_create_func(
/*===========*/
/* out, own: created table */
ibool in_btr_search, /* in: TRUE if the hash table is used in
the btr_search module */
ulint n, /* in: number of array cells */
ulint n_mutexes, /* in: number of mutexes to protect the
hash table: must be a power of 2, or 0 */
ulint mutex_level) /* in: level of the mutexes in the latching
#ifdef UNIV_SYNC_DEBUG
ulint mutex_level, /* in: level of the mutexes in the latching
order: this is used in the debug version */
#endif /* UNIV_SYNC_DEBUG */
ulint n_mutexes) /* in: number of mutexes to protect the
hash table: must be a power of 2, or 0 */
{
hash_table_t* table;
ulint i;
......
......@@ -129,13 +129,15 @@ hash_table_free(
Creates a mutex array to protect a hash table. */
void
hash_create_mutexes(
/*================*/
hash_create_mutexes_func(
/*=====================*/
hash_table_t* table, /* in: hash table */
ulint n_mutexes, /* in: number of mutexes, must be a
power of 2 */
ulint sync_level) /* in: latching order level of the
#ifdef UNIV_SYNC_DEBUG
ulint sync_level, /* in: latching order level of the
mutexes: used in the debug version */
#endif /* UNIV_SYNC_DEBUG */
ulint n_mutexes) /* in: number of mutexes, must be a
power of 2 */
{
ulint i;
......
......@@ -6599,22 +6599,23 @@ innodb_mutex_show_status(
{
char buf1[IO_SIZE], buf2[IO_SIZE];
mutex_t* mutex;
#ifdef UNIV_DEBUG
ulint rw_lock_count= 0;
ulint rw_lock_count_spin_loop= 0;
ulint rw_lock_count_spin_rounds= 0;
ulint rw_lock_count_os_wait= 0;
ulint rw_lock_count_os_yield= 0;
ulonglong rw_lock_wait_time= 0;
#endif /* UNIV_DEBUG */
uint hton_name_len= strlen(innobase_hton_name), buf1len, buf2len;
DBUG_ENTER("innodb_mutex_show_status");
#ifdef MUTEX_PROTECT_TO_BE_ADDED_LATER
mutex_enter(&mutex_list_mutex);
#endif
mutex_enter_noninline(&mutex_list_mutex);
mutex = UT_LIST_GET_FIRST(mutex_list);
while (mutex != NULL) {
#ifdef UNIV_DEBUG
if (mutex->mutex_type != 1) {
if (mutex->count_using > 0) {
buf1len= my_snprintf(buf1, sizeof(buf1),
......@@ -6635,9 +6636,8 @@ innodb_mutex_show_status(
if (stat_print(thd, innobase_hton_name,
hton_name_len, buf1, buf1len,
buf2, buf2len)) {
#ifdef MUTEX_PROTECT_TO_BE_ADDED_LATER
mutex_exit(&mutex_list_mutex);
#endif
mutex_exit_noninline(
&mutex_list_mutex);
DBUG_RETURN(1);
}
}
......@@ -6650,10 +6650,26 @@ innodb_mutex_show_status(
rw_lock_count_os_yield += mutex->count_os_yield;
rw_lock_wait_time += mutex->lspent_time;
}
#else /* UNIV_DEBUG */
buf1len= my_snprintf(buf1, sizeof(buf1), "%s:%lu",
mutex->cfile_name, (ulong) mutex->cline);
buf2len= my_snprintf(buf2, sizeof(buf2), "os_waits=%lu",
mutex->count_os_wait);
if (stat_print(thd, innobase_hton_name,
hton_name_len, buf1, buf1len,
buf2, buf2len)) {
mutex_exit_noninline(&mutex_list_mutex);
DBUG_RETURN(1);
}
#endif /* UNIV_DEBUG */
mutex = UT_LIST_GET_NEXT(list, mutex);
}
mutex_exit_noninline(&mutex_list_mutex);
#ifdef UNIV_DEBUG
buf2len= my_snprintf(buf2, sizeof(buf2),
"count=%lu, spin_waits=%lu, spin_rounds=%lu, "
"os_waits=%lu, os_yields=%lu, os_wait_times=%lu",
......@@ -6666,10 +6682,7 @@ innodb_mutex_show_status(
STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) {
DBUG_RETURN(1);
}
#ifdef MUTEX_PROTECT_TO_BE_ADDED_LATER
mutex_exit(&mutex_list_mutex);
#endif
#endif /* UNIV_DEBUG */
DBUG_RETURN(FALSE);
}
......
......@@ -41,16 +41,23 @@ Creates a hash table with >= n array cells. The actual number of cells is
chosen to be a prime number slightly bigger than n. */
hash_table_t*
ha_create(
/*======*/
ha_create_func(
/*===========*/
/* out, own: created table */
ibool in_btr_search, /* in: TRUE if the hash table is used in
the btr_search module */
ulint n, /* in: number of array cells */
ulint n_mutexes, /* in: number of mutexes to protect the
hash table: must be a power of 2 */
ulint mutex_level); /* in: level of the mutexes in the latching
#ifdef UNIV_SYNC_DEBUG
ulint mutex_level, /* in: level of the mutexes in the latching
order: this is used in the debug version */
#endif /* UNIV_SYNC_DEBUG */
ulint n_mutexes); /* in: number of mutexes to protect the
hash table: must be a power of 2 */
#ifdef UNIV_SYNC_DEBUG
# define ha_create(b,n_c,n_m,level) ha_create_func(b,n_c,level,n_m)
#else /* UNIV_SYNC_DEBUG */
# define ha_create(b,n_c,n_m,level) ha_create_func(b,n_c,n_m)
#endif /* UNIV_SYNC_DEBUG */
/*****************************************************************
Inserts an entry into a hash table. If an entry with the same fold number
is found, its node is updated to point to the new data, and no new node
......
......@@ -31,12 +31,20 @@ hash_create(
Creates a mutex array to protect a hash table. */
void
hash_create_mutexes(
/*================*/
hash_create_mutexes_func(
/*=====================*/
hash_table_t* table, /* in: hash table */
ulint n_mutexes, /* in: number of mutexes */
ulint sync_level); /* in: latching order level of the
#ifdef UNIV_SYNC_DEBUG
ulint sync_level, /* in: latching order level of the
mutexes: used in the debug version */
#endif /* UNIV_SYNC_DEBUG */
ulint n_mutexes); /* in: number of mutexes */
#ifdef UNIV_SYNC_DEBUG
# define hash_create_mutexes(t,n,level) hash_create_mutexes_func(t,level,n)
#else /* UNIV_SYNC_DEBUG */
# define hash_create_mutexes(t,n,level) hash_create_mutexes_func(t,n)
#endif /* UNIV_SYNC_DEBUG */
/*****************************************************************
Frees a hash table. */
......
......@@ -61,8 +61,18 @@ Creates, or rather, initializes an rw-lock object in a specified memory
location (which must be appropriately aligned). The rw-lock is initialized
to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free
is necessary only if the memory block containing it is freed. */
#define rw_lock_create(L, level) \
rw_lock_create_func((L), (level), __FILE__, __LINE__, #L)
#ifdef UNIV_DEBUG
# ifdef UNIV_SYNC_DEBUG
# define rw_lock_create(L, level) \
rw_lock_create_func((L), (level), #L, __FILE__, __LINE__)
# else /* UNIV_SYNC_DEBUG */
# define rw_lock_create(L, level) \
rw_lock_create_func((L), #L, __FILE__, __LINE__)
# endif /* UNIV_SYNC_DEBUG */
#else /* UNIV_DEBUG */
# define rw_lock_create(L, level) \
rw_lock_create_func((L), __FILE__, __LINE__)
#endif /* UNIV_DEBUG */
/**********************************************************************
Creates, or rather, initializes an rw-lock object in a specified memory
......@@ -74,10 +84,14 @@ void
rw_lock_create_func(
/*================*/
rw_lock_t* lock, /* in: pointer to memory */
#ifdef UNIV_DEBUG
# ifdef UNIV_SYNC_DEBUG
ulint level, /* in: level */
# endif /* UNIV_SYNC_DEBUG */
const char* cmutex_name, /* in: mutex name */
#endif /* UNIV_DEBUG */
const char* cfile_name, /* in: file name where created */
ulint cline, /* in: file line where created */
const char* cmutex_name); /* in: mutex name */
ulint cline); /* in: file line where created */
/**********************************************************************
Calling this function is obligatory only if the memory buffer containing
the rw-lock is freed. Removes an rw-lock object from the global list. The
......
......@@ -39,8 +39,18 @@ location (which must be appropriately aligned). The mutex is initialized
in the reset state. Explicit freeing of the mutex with mutex_free is
necessary only if the memory block containing it is freed. */
#define mutex_create(M, level) \
mutex_create_func((M), (level), __FILE__, __LINE__, #M)
#ifdef UNIV_DEBUG
# ifdef UNIV_SYNC_DEBUG
# define mutex_create(M, level) \
mutex_create_func((M), #M, (level), __FILE__, __LINE__)
# else
# define mutex_create(M, level) \
mutex_create_func((M), #M, __FILE__, __LINE__)
# endif
#else
# define mutex_create(M, level) \
mutex_create_func((M), __FILE__, __LINE__)
#endif
/**********************************************************************
Creates, or rather, initializes a mutex object in a specified memory
......@@ -52,10 +62,14 @@ void
mutex_create_func(
/*==============*/
mutex_t* mutex, /* in: pointer to memory */
#ifdef UNIV_DEBUG
const char* cmutex_name, /* in: mutex name */
# ifdef UNIV_SYNC_DEBUG
ulint level, /* in: level */
# endif /* UNIV_SYNC_DEBUG */
#endif /* UNIV_DEBUG */
const char* cfile_name, /* in: file name where created */
ulint cline, /* in: file line where created */
const char* cmutex_name); /* in: mutex name */
ulint cline); /* in: file line where created */
/**********************************************************************
Calling this function is obligatory only if the memory buffer containing
the mutex is freed. Removes a mutex object from the mutex list. The mutex
......@@ -467,26 +481,29 @@ struct mutex_struct {
ulint line; /* Line where the mutex was locked */
os_thread_id_t thread_id; /* Debug version: The thread id of the
thread which locked the mutex. */
#endif /* UNIV_SYNC_DEBUG */
ulint level; /* Level in the global latching order */
#endif /* UNIV_SYNC_DEBUG */
const char* cfile_name;/* File name where mutex created */
ulint cline; /* Line where created */
ulint magic_n;
ulint cline; /* Line where created */
#ifdef UNIV_DEBUG
ulint magic_n;
# define MUTEX_MAGIC_N (ulint)979585
#endif /* UNIV_DEBUG */
#ifndef UNIV_HOTBACKUP
ulong count_using; /* count of times mutex used */
ulong count_spin_loop; /* count of spin loops */
ulong count_spin_rounds; /* count of spin rounds */
ulong count_os_wait; /* count of os_wait */
ulong count_os_yield; /* count of os_wait */
ulonglong lspent_time; /* mutex os_wait timer msec */
ulonglong lmax_spent_time; /* mutex os_wait timer msec */
const char* cmutex_name;/* mutex name */
ulint mutex_type;/* 0 - usual mutex 1 - rw_lock mutex */
ulong count_os_wait; /* count of os_wait */
# ifdef UNIV_DEBUG
ulong count_using; /* count of times mutex used */
ulong count_spin_loop; /* count of spin loops */
ulong count_spin_rounds; /* count of spin rounds */
ulong count_os_yield; /* count of os_wait */
ulonglong lspent_time; /* mutex os_wait timer msec */
ulonglong lmax_spent_time; /* mutex os_wait timer msec */
const char* cmutex_name;/* mutex name */
ulint mutex_type;/* 0 - usual mutex 1 - rw_lock mutex */
# endif /* UNIV_DEBUG */
#endif /* !UNIV_HOTBACKUP */
};
#define MUTEX_MAGIC_N (ulint)979585
/* The global array of wait cells for implementation of the databases own
mutexes and read-write locks. Appears here for debugging purposes only! */
......
......@@ -254,9 +254,9 @@ mutex_enter_func(
/* Note that we do not peek at the value of lock_word before trying
the atomic test_and_set; we could peek, and possibly save time. */
#ifndef UNIV_HOTBACKUP
#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
mutex->count_using++;
#endif /* UNIV_HOTBACKUP */
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
if (!mutex_test_and_set(mutex)) {
#ifdef UNIV_SYNC_DEBUG
......
......@@ -89,11 +89,14 @@ void
rw_lock_create_func(
/*================*/
rw_lock_t* lock, /* in: pointer to memory */
ulint level __attribute__((unused)),
/* in: level */
#ifdef UNIV_DEBUG
# ifdef UNIV_SYNC_DEBUG
ulint level, /* in: level */
# endif /* UNIV_SYNC_DEBUG */
const char* cmutex_name, /* in: mutex name */
#endif /* UNIV_DEBUG */
const char* cfile_name, /* in: file name where created */
ulint cline, /* in: file line where created */
const char* cmutex_name) /* in: mutex name */
ulint cline) /* in: file line where created */
{
/* If this is the very first time a synchronization object is
created, then the following call initializes the sync system. */
......@@ -103,10 +106,10 @@ rw_lock_create_func(
lock->mutex.cfile_name = cfile_name;
lock->mutex.cline = cline;
#ifndef UNIV_HOTBACKUP
#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
lock->mutex.cmutex_name = cmutex_name;
lock->mutex.mutex_type = 1;
#endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
rw_lock_set_waiters(lock, 0);
rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED);
......
......@@ -201,10 +201,14 @@ void
mutex_create_func(
/*==============*/
mutex_t* mutex, /* in: pointer to memory */
#ifdef UNIV_DEBUG
const char* cmutex_name, /* in: mutex name */
# ifdef UNIV_SYNC_DEBUG
ulint level, /* in: level */
# endif /* UNIV_SYNC_DEBUG */
#endif /* UNIV_DEBUG */
const char* cfile_name, /* in: file name where created */
ulint cline, /* in: file line where created */
const char* cmutex_name) /* in: mutex name */
ulint cline) /* in: file line where created */
{
#if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER)
mutex_reset_lock_word(mutex);
......@@ -213,15 +217,19 @@ mutex_create_func(
mutex->lock_word = 0;
#endif
mutex_set_waiters(mutex, 0);
#ifdef UNIV_DEBUG
mutex->magic_n = MUTEX_MAGIC_N;
#endif /* UNIV_DEBUG */
#ifdef UNIV_SYNC_DEBUG
mutex->line = 0;
mutex->file_name = "not yet reserved";
#endif /* UNIV_SYNC_DEBUG */
mutex->level = level;
#endif /* UNIV_SYNC_DEBUG */
mutex->cfile_name = cfile_name;
mutex->cline = cline;
#ifndef UNIV_HOTBACKUP
mutex->count_os_wait = 0;
# ifdef UNIV_DEBUG
mutex->cmutex_name= cmutex_name;
mutex->count_using= 0;
mutex->mutex_type= 0;
......@@ -229,8 +237,8 @@ mutex_create_func(
mutex->lmax_spent_time= 0;
mutex->count_spin_loop= 0;
mutex->count_spin_rounds= 0;
mutex->count_os_wait= 0;
mutex->count_os_yield= 0;
# endif /* UNIV_DEBUG */
#endif /* !UNIV_HOTBACKUP */
/* Check that lock_word is aligned; this is important on Intel */
......@@ -249,9 +257,8 @@ mutex_create_func(
mutex_enter(&mutex_list_mutex);
if (UT_LIST_GET_LEN(mutex_list) > 0) {
ut_a(UT_LIST_GET_FIRST(mutex_list)->magic_n == MUTEX_MAGIC_N);
}
ut_ad(UT_LIST_GET_LEN(mutex_list) == 0
|| UT_LIST_GET_FIRST(mutex_list)->magic_n == MUTEX_MAGIC_N);
UT_LIST_ADD_FIRST(list, mutex_list, mutex);
......@@ -280,14 +287,12 @@ mutex_free(
mutex_enter(&mutex_list_mutex);
if (UT_LIST_GET_PREV(list, mutex)) {
ut_a(UT_LIST_GET_PREV(list, mutex)->magic_n
== MUTEX_MAGIC_N);
}
if (UT_LIST_GET_NEXT(list, mutex)) {
ut_a(UT_LIST_GET_NEXT(list, mutex)->magic_n
== MUTEX_MAGIC_N);
}
ut_ad(!UT_LIST_GET_PREV(list, mutex)
|| UT_LIST_GET_PREV(list, mutex)->magic_n
== MUTEX_MAGIC_N);
ut_ad(!UT_LIST_GET_NEXT(list, mutex)
|| UT_LIST_GET_NEXT(list, mutex)->magic_n
== MUTEX_MAGIC_N);
UT_LIST_REMOVE(list, mutex_list, mutex);
......@@ -300,8 +305,9 @@ mutex_free(
/* If we free the mutex protecting the mutex list (freeing is
not necessary), we have to reset the magic number AFTER removing
it from the list. */
#ifdef UNIV_DEBUG
mutex->magic_n = 0;
#endif /* UNIV_DEBUG */
}
/************************************************************************
......@@ -333,6 +339,7 @@ mutex_enter_nowait(
return(1);
}
#ifdef UNIV_DEBUG
/**********************************************************************
Checks that the mutex has been initialized. */
......@@ -346,6 +353,7 @@ mutex_validate(
return(TRUE);
}
#endif /* UNIV_DEBUG */
/**********************************************************************
Sets the waiters field in a mutex. */
......@@ -381,13 +389,13 @@ mutex_spin_wait(
{
ulint index; /* index of the reserved wait cell */
ulint i; /* spin round count */
#ifndef UNIV_HOTBACKUP
#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
ib_longlong lstart_time = 0, lfinish_time; /* for timing os_wait */
ulint ltime_diff;
ulint sec;
ulint ms;
uint timer_started = 0;
#endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
ut_ad(mutex);
mutex_loop:
......@@ -401,10 +409,10 @@ mutex_spin_wait(
a memory word. */
spin_loop:
#ifndef UNIV_HOTBACKUP
#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
mutex_spin_wait_count++;
mutex->count_spin_loop++;
#endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
while (mutex_get_lock_word(mutex) != 0 && i < SYNC_SPIN_ROUNDS) {
if (srv_spin_wait_delay) {
......@@ -415,14 +423,14 @@ mutex_spin_wait(
}
if (i == SYNC_SPIN_ROUNDS) {
#ifndef UNIV_HOTBACKUP
#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
mutex->count_os_yield++;
if (timed_mutexes == 1 && timer_started==0) {
ut_usectime(&sec, &ms);
lstart_time= (ib_longlong)sec * 1000000 + ms;
timer_started = 1;
}
#endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
os_thread_yield();
}
......@@ -436,9 +444,9 @@ mutex_spin_wait(
mutex_spin_round_count += i;
#ifndef UNIV_HOTBACKUP
#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
mutex->count_spin_rounds += i;
#endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
if (mutex_test_and_set(mutex) == 0) {
/* Succeeded! */
......@@ -519,6 +527,7 @@ mutex_spin_wait(
#ifndef UNIV_HOTBACKUP
mutex->count_os_wait++;
# ifdef UNIV_DEBUG
/* !!!!! Sometimes os_wait can be called without os_thread_yield */
if (timed_mutexes == 1 && timer_started==0) {
......@@ -526,13 +535,14 @@ mutex_spin_wait(
lstart_time= (ib_longlong)sec * 1000000 + ms;
timer_started = 1;
}
# endif /* UNIV_DEBUG */
#endif /* !UNIV_HOTBACKUP */
sync_array_wait_event(sync_primary_wait_array, index);
goto mutex_loop;
finish_timing:
#ifndef UNIV_HOTBACKUP
#if defined UNIV_DEBUG && !defined UNIV_HOTBACKUP
if (timed_mutexes == 1 && timer_started==1) {
ut_usectime(&sec, &ms);
lfinish_time= (ib_longlong)sec * 1000000 + ms;
......@@ -544,7 +554,7 @@ mutex_spin_wait(
mutex->lmax_spent_time= ltime_diff;
}
}
#endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
return;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment