diff options
Diffstat (limited to 'innobase')
-rw-r--r-- | innobase/include/que0que.h | 6 | ||||
-rw-r--r-- | innobase/include/srv0srv.h | 5 | ||||
-rw-r--r-- | innobase/include/sync0rw.h | 8 | ||||
-rw-r--r-- | innobase/include/sync0sync.h | 24 | ||||
-rw-r--r-- | innobase/include/sync0sync.ic | 6 | ||||
-rw-r--r-- | innobase/include/univ.i | 1 | ||||
-rw-r--r-- | innobase/que/que0que.c | 1 | ||||
-rw-r--r-- | innobase/row/row0mysql.c | 7 | ||||
-rw-r--r-- | innobase/row/row0sel.c | 4 | ||||
-rw-r--r-- | innobase/srv/srv0srv.c | 50 | ||||
-rw-r--r-- | innobase/sync/sync0rw.c | 7 | ||||
-rw-r--r-- | innobase/sync/sync0sync.c | 260 | ||||
-rw-r--r-- | innobase/ut/ut0ut.c | 15 |
13 files changed, 273 insertions, 121 deletions
diff --git a/innobase/include/que0que.h b/innobase/include/que0que.h index e1874edcaf2..d45ae032ddb 100644 --- a/innobase/include/que0que.h +++ b/innobase/include/que0que.h @@ -359,6 +359,7 @@ struct que_thr_struct{ the control came */ ulint resource; /* resource usage of the query thread thus far */ + ulint lock_state; /* lock state of thread (table or row) */ }; #define QUE_THR_MAGIC_N 8476583 @@ -482,6 +483,11 @@ struct que_fork_struct{ #define QUE_THR_SUSPENDED 7 #define QUE_THR_ERROR 8 +/* Query thread lock states */ +#define QUE_THR_LOCK_NOLOCK 0 +#define QUE_THR_LOCK_ROW 1 +#define QUE_THR_LOCK_TABLE 2 + /* From where the cursor position is counted */ #define QUE_CUR_NOT_DEFINED 1 #define QUE_CUR_START 2 diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h index 84b7d14ca00..5f752717fcc 100644 --- a/innobase/include/srv0srv.h +++ b/innobase/include/srv0srv.h @@ -525,6 +525,11 @@ struct export_var_struct{ ulint innodb_pages_created; ulint innodb_pages_read; ulint innodb_pages_written; + ulint innodb_row_lock_waits; + ulint innodb_row_lock_current_waits; + ib_longlong innodb_row_lock_time; + ulint innodb_row_lock_time_avg; + ulint innodb_row_lock_time_max; ulint innodb_rows_read; ulint innodb_rows_inserted; ulint innodb_rows_updated; diff --git a/innobase/include/sync0rw.h b/innobase/include/sync0rw.h index 9a988a03e92..6e3a4cf4dc7 100644 --- a/innobase/include/sync0rw.h +++ b/innobase/include/sync0rw.h @@ -61,8 +61,9 @@ 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) rw_lock_create_func((L), __FILE__, __LINE__) +#define rw_lock_create(L) rw_lock_create_func(\ + (L), __FILE__, __LINE__, __STRING(L)) + /*=====================*/ /********************************************************************** Creates, or rather, initializes an rw-lock object in a specified memory @@ -75,7 +76,8 @@ rw_lock_create_func( /*================*/ rw_lock_t* lock, /* in: pointer to memory */ const char* cfile_name, /* in: file name where created */ - ulint cline); /* in: file line where created */ + ulint cline, /* in: file line where created */ + const char* cmutex_name); /* in: mutex name */ /********************************************************************** 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 diff --git a/innobase/include/sync0sync.h b/innobase/include/sync0sync.h index 8e0ec715b12..98d61c129b1 100644 --- a/innobase/include/sync0sync.h +++ b/innobase/include/sync0sync.h @@ -17,6 +17,8 @@ Created 9/5/1995 Heikki Tuuri #include "os0sync.h" #include "sync0arr.h" +extern my_bool timed_mutexes; + /********************************************************************** Initializes the synchronization data structures. */ @@ -35,8 +37,7 @@ 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) mutex_create_func((M), __FILE__, __LINE__) +#define mutex_create(M) mutex_create_func((M), __FILE__, __LINE__, __STRING(M)) /*===================*/ /********************************************************************** Creates, or rather, initializes a mutex object in a specified memory @@ -49,7 +50,8 @@ mutex_create_func( /*==============*/ mutex_t* mutex, /* in: pointer to memory */ const char* cfile_name, /* in: file name where created */ - ulint cline); /* in: file line where created */ + ulint cline, /* in: file line where created */ + const char* cmutex_name); /* in: mutex name */ /********************************************************************** 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 @@ -471,6 +473,15 @@ struct mutex_struct { const char* cfile_name;/* File name where mutex created */ ulint cline; /* Line where created */ ulint magic_n; + 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 */ }; #define MUTEX_MAGIC_N (ulint)979585 @@ -504,6 +515,13 @@ extern ibool sync_order_checks_on; /* This variable is set to TRUE when sync_init is called */ extern ibool sync_initialized; +/* Global list of database mutexes (not OS mutexes) created. */ +UT_LIST_BASE_NODE_T(mutex_t) mutex_list; + +/* Mutex protecting the mutex_list variable */ +mutex_t mutex_list_mutex; + + #ifndef UNIV_NONINL #include "sync0sync.ic" #endif diff --git a/innobase/include/sync0sync.ic b/innobase/include/sync0sync.ic index aaf5e1fd9e9..1731b47db58 100644 --- a/innobase/include/sync0sync.ic +++ b/innobase/include/sync0sync.ic @@ -249,8 +249,11 @@ 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. */ + + mutex->count_using++; - if (!mutex_test_and_set(mutex)) { + if (!mutex_test_and_set(mutex)) + { #ifdef UNIV_SYNC_DEBUG mutex_set_debug_info(mutex, file_name, line); #endif @@ -258,4 +261,5 @@ mutex_enter_func( } mutex_spin_wait(mutex, file_name, line); + } diff --git a/innobase/include/univ.i b/innobase/include/univ.i index be71d4211b3..80024f71992 100644 --- a/innobase/include/univ.i +++ b/innobase/include/univ.i @@ -88,6 +88,7 @@ memory is read outside the allocated blocks. */ #define UNIV_SEARCH_DEBUG #define UNIV_SYNC_PERF_STAT #define UNIV_SEARCH_PERF_STAT +#define UNIV_SRV_PRINT_LATCH_WAITS; */ #define UNIV_LIGHT_MEM_DEBUG diff --git a/innobase/que/que0que.c b/innobase/que/que0que.c index 22878dec27f..a0a6adf9b83 100644 --- a/innobase/que/que0que.c +++ b/innobase/que/que0que.c @@ -163,6 +163,7 @@ que_thr_create( thr->run_node = NULL; thr->resource = 0; + thr->lock_state = QUE_THR_LOCK_NOLOCK; UT_LIST_ADD_LAST(thrs, parent->thrs, thr); diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index e959c28f6bb..0a2e9e5eaad 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -937,9 +937,10 @@ run_again: if (err != DB_SUCCESS) { que_thr_stop_for_mysql(thr); - + thr->lock_state= QUE_THR_LOCK_ROW; was_lock_wait = row_mysql_handle_errors(&err, trx, thr, &savept); + thr->lock_state= QUE_THR_LOCK_NOLOCK; if (was_lock_wait) { goto run_again; } @@ -1171,9 +1172,11 @@ run_again: return((int) err); } - + + thr->lock_state= QUE_THR_LOCK_ROW; was_lock_wait = row_mysql_handle_errors(&err, trx, thr, &savept); + thr->lock_state= QUE_THR_LOCK_NOLOCK;; if (was_lock_wait) { goto run_again; } diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index a3d844d1dac..c079557ca8b 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -3791,8 +3791,10 @@ lock_wait_or_error: que_thr_stop_for_mysql(thr); + thr->lock_state= QUE_THR_LOCK_ROW; was_lock_wait = row_mysql_handle_errors(&err, trx, thr, NULL); - + thr->lock_state= QUE_THR_LOCK_NOLOCK; + if (was_lock_wait) { mtr_start(&mtr); diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index 83d4fb4d39d..aa2a7fa9169 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -346,6 +346,12 @@ static ulint srv_n_rows_updated_old = 0; static ulint srv_n_rows_deleted_old = 0; static ulint srv_n_rows_read_old = 0; +ulint srv_n_lock_wait_count= 0; +ulint srv_n_lock_wait_current_count= 0; +ib_longlong srv_n_lock_wait_time= 0; +ulint srv_n_lock_max_wait_time= 0; + + /* Set the following to 0 if you want InnoDB to write messages on stderr on startup/shutdown @@ -1378,7 +1384,11 @@ srv_suspend_mysql_thread( trx_t* trx; ibool had_dict_lock = FALSE; ibool was_declared_inside_innodb = FALSE; - + ib_longlong start_time, finish_time; + ulint diff_time; + ulint sec; + ulint ms; + #ifdef UNIV_SYNC_DEBUG ut_ad(!mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ @@ -1420,7 +1430,15 @@ srv_suspend_mysql_thread( os_event_reset(event); slot->suspend_time = ut_time(); + if (thr->lock_state == QUE_THR_LOCK_ROW) + { + srv_n_lock_wait_count++; + srv_n_lock_wait_current_count++; + + ut_usectime(&sec, &ms); + start_time= (ib_longlong)sec * 1000000 + ms; + } /* Wake the lock timeout monitor thread, if it is suspended */ os_event_set(srv_lock_timeout_thread_event); @@ -1471,7 +1489,22 @@ srv_suspend_mysql_thread( slot->in_use = FALSE; wait_time = ut_difftime(ut_time(), slot->suspend_time); - + + if (thr->lock_state == QUE_THR_LOCK_ROW) + { + ut_usectime(&sec, &ms); + finish_time= (ib_longlong)sec * 1000000 + ms; + + diff_time= finish_time-start_time; + + srv_n_lock_wait_current_count--; + srv_n_lock_wait_time= srv_n_lock_wait_time + diff_time; + if (diff_time > srv_n_lock_max_wait_time) + { + srv_n_lock_max_wait_time= diff_time; + } + } + if (trx->was_chosen_as_deadlock_victim) { trx->error_state = DB_DEADLOCK; @@ -1689,15 +1722,14 @@ srv_printf_innodb_monitor( (srv_n_rows_read - srv_n_rows_read_old) / time_elapsed); - srv_n_rows_inserted_old = srv_n_rows_inserted; + srv_n_rows_inserted_old = srv_n_rows_inserted; srv_n_rows_updated_old = srv_n_rows_updated; srv_n_rows_deleted_old = srv_n_rows_deleted; srv_n_rows_read_old = srv_n_rows_read; - fputs("----------------------------\n" + fputs("----------------------------\n" "END OF INNODB MONITOR OUTPUT\n" "============================\n", file); - mutex_exit(&srv_innodb_monitor_mutex); fflush(file); } @@ -1746,11 +1778,19 @@ srv_export_innodb_status(void) export_vars.innodb_pages_created= buf_pool->n_pages_created; export_vars.innodb_pages_read= buf_pool->n_pages_read; export_vars.innodb_pages_written= buf_pool->n_pages_written; + export_vars.innodb_row_lock_waits= srv_n_lock_wait_count; + export_vars.innodb_row_lock_current_waits= srv_n_lock_wait_current_count; + export_vars.innodb_row_lock_time= srv_n_lock_wait_time / 10000; + export_vars.innodb_row_lock_time_avg= + (srv_n_lock_wait_count > 0) ? + (srv_n_lock_wait_time / 10000 / srv_n_lock_wait_count) : 0; + export_vars.innodb_row_lock_time_max= srv_n_lock_max_wait_time / 10000; export_vars.innodb_rows_read= srv_n_rows_read; export_vars.innodb_rows_inserted= srv_n_rows_inserted; export_vars.innodb_rows_updated= srv_n_rows_updated; export_vars.innodb_rows_deleted= srv_n_rows_deleted; mutex_exit(&srv_innodb_monitor_mutex); + } /************************************************************************* diff --git a/innobase/sync/sync0rw.c b/innobase/sync/sync0rw.c index 77757685208..e57974a375b 100644 --- a/innobase/sync/sync0rw.c +++ b/innobase/sync/sync0rw.c @@ -90,7 +90,8 @@ rw_lock_create_func( /*================*/ rw_lock_t* lock, /* in: pointer to memory */ const char* cfile_name, /* in: file name where created */ - ulint cline) /* in: file line where created */ + ulint cline, /* in: file line where created */ + const char* cmutex_name) /* in: mutex name */ { /* If this is the very first time a synchronization object is created, then the following call initializes @@ -101,7 +102,9 @@ rw_lock_create_func( lock->mutex.cfile_name = cfile_name; lock->mutex.cline = cline; - + lock->mutex.cmutex_name = cmutex_name; + lock->mutex.mutex_type = 1; + rw_lock_set_waiters(lock, 0); rw_lock_set_writer(lock, RW_LOCK_NOT_LOCKED); lock->writer_count = 0; diff --git a/innobase/sync/sync0sync.c b/innobase/sync/sync0sync.c index 86306e49cac..fb46c692830 100644 --- a/innobase/sync/sync0sync.c +++ b/innobase/sync/sync0sync.c @@ -129,11 +129,6 @@ sync_array_t* sync_primary_wait_array; /* This variable is set to TRUE when sync_init is called */ ibool sync_initialized = FALSE; -/* Global list of database mutexes (not OS mutexes) created. */ -UT_LIST_BASE_NODE_T(mutex_t) mutex_list; - -/* Mutex protecting the mutex_list variable */ -mutex_t mutex_list_mutex; typedef struct sync_level_struct sync_level_t; typedef struct sync_thread_struct sync_thread_t; @@ -202,7 +197,8 @@ mutex_create_func( /*==============*/ mutex_t* mutex, /* in: pointer to memory */ const char* cfile_name, /* in: file name where created */ - ulint cline) /* in: file line where created */ + ulint cline, /* in: file line where created */ + const char* cmutex_name) /* in: mutex name */ { #if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER) mutex_reset_lock_word(mutex); @@ -219,6 +215,16 @@ mutex_create_func( mutex->level = SYNC_LEVEL_NONE; mutex->cfile_name = cfile_name; mutex->cline = cline; + mutex->cmutex_name= cmutex_name; + mutex->count_using= 0; + mutex->mutex_type= 0; + mutex->lspent_time= 0; + 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; + /* Check that lock_word is aligned; this is important on Intel */ ut_ad(((ulint)(&(mutex->lock_word))) % 4 == 0); @@ -355,135 +361,180 @@ for the mutex before suspending the thread. */ void mutex_spin_wait( /*============*/ - mutex_t* mutex, /* in: pointer to mutex */ - const char* file_name, /* in: file name where - mutex requested */ - ulint line) /* in: line where requested */ + mutex_t* mutex, /* in: pointer to mutex */ + const char* file_name, /* in: file name where + mutex requested */ + ulint line) /* in: line where requested */ { - ulint index; /* index of the reserved wait cell */ - ulint i; /* spin round count */ - - ut_ad(mutex); + ulint index; /* index of the reserved wait cell */ + ulint i; /* spin round count */ + ib_longlong lstart_time, lfinish_time; /* for timing os_wait */ + ulint ltime_diff; + ulint sec; + ulint ms; -mutex_loop: + uint timer_started = 0; - i = 0; + ut_ad(mutex); - /* Spin waiting for the lock word to become zero. Note that we do not - have to assume that the read access to the lock word is atomic, as the - actual locking is always committed with atomic test-and-set. In - reality, however, all processors probably have an atomic read of a - memory word. */ - -spin_loop: - mutex_spin_wait_count++; +mutex_loop: - while (mutex_get_lock_word(mutex) != 0 && i < SYNC_SPIN_ROUNDS) { + i = 0; - if (srv_spin_wait_delay) { - ut_delay(ut_rnd_interval(0, srv_spin_wait_delay)); - } - - i++; - } +/* Spin waiting for the lock word to become zero. Note that we do not + have to assume that the read access to the lock word is atomic, as the + actual locking is always committed with atomic test-and-set. In + reality, however, all processors probably have an atomic read of a + memory word. */ - if (i == SYNC_SPIN_ROUNDS) { - os_thread_yield(); - } +spin_loop: + mutex_spin_wait_count++; + mutex->count_spin_loop++; + + while (mutex_get_lock_word(mutex) != 0 && i < SYNC_SPIN_ROUNDS) + { + if (srv_spin_wait_delay) + { + ut_delay(ut_rnd_interval(0, srv_spin_wait_delay)); + } + + i++; + } + + if (i == SYNC_SPIN_ROUNDS) + { + 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; + } + os_thread_yield(); + } + +#ifdef UNIV_SRV_PRINT_LATCH_WAITS + fprintf(stderr, + "Thread %lu spin wait mutex at %p cfile %s cline %lu rnds %lu\n", + (ulong) os_thread_pf(os_thread_get_curr_id()), mutex, + mutex->cfile_name, (ulong) mutex->cline, (ulong) i); +#endif - if (srv_print_latch_waits) { - fprintf(stderr, - "Thread %lu spin wait mutex at %p cfile %s cline %lu rnds %lu\n", - (ulong) os_thread_pf(os_thread_get_curr_id()), mutex, - mutex->cfile_name, (ulong) mutex->cline, (ulong) i); - } + mutex_spin_round_count += i; - mutex_spin_round_count += i; + mutex->count_spin_rounds += i; - if (mutex_test_and_set(mutex) == 0) { - /* Succeeded! */ + if (mutex_test_and_set(mutex) == 0) + { + /* Succeeded! */ #ifdef UNIV_SYNC_DEBUG - mutex_set_debug_info(mutex, file_name, line); + mutex_set_debug_info(mutex, file_name, line); #endif - return; - } + goto finish_timing; + } - /* We may end up with a situation where lock_word is - 0 but the OS fast mutex is still reserved. On FreeBSD - the OS does not seem to schedule a thread which is constantly - calling pthread_mutex_trylock (in mutex_test_and_set - implementation). Then we could end up spinning here indefinitely. - The following 'i++' stops this infinite spin. */ + /* We may end up with a situation where lock_word is + 0 but the OS fast mutex is still reserved. On FreeBSD + the OS does not seem to schedule a thread which is constantly + calling pthread_mutex_trylock (in mutex_test_and_set + implementation). Then we could end up spinning here indefinitely. + The following 'i++' stops this infinite spin. */ - i++; - - if (i < SYNC_SPIN_ROUNDS) { + i++; - goto spin_loop; - } + if (i < SYNC_SPIN_ROUNDS) + { + goto spin_loop; + } - sync_array_reserve_cell(sync_primary_wait_array, mutex, - SYNC_MUTEX, - file_name, line, - &index); + sync_array_reserve_cell(sync_primary_wait_array, mutex, + SYNC_MUTEX, file_name, line, &index); - mutex_system_call_count++; + mutex_system_call_count++; - /* The memory order of the array reservation and the change in the - waiters field is important: when we suspend a thread, we first - reserve the cell and then set waiters field to 1. When threads are - released in mutex_exit, the waiters field is first set to zero and - then the event is set to the signaled state. */ - - mutex_set_waiters(mutex, 1); + /* The memory order of the array reservation and the change in the + waiters field is important: when we suspend a thread, we first + reserve the cell and then set waiters field to 1. When threads are + released in mutex_exit, the waiters field is first set to zero and + then the event is set to the signaled state. */ + + mutex_set_waiters(mutex, 1); - /* Try to reserve still a few times */ - for (i = 0; i < 4; i++) { - if (mutex_test_and_set(mutex) == 0) { + /* Try to reserve still a few times */ + for (i = 0; i < 4; i++) + { + if (mutex_test_and_set(mutex) == 0) + { + /* Succeeded! Free the reserved wait cell */ - /* Succeeded! Free the reserved wait cell */ + sync_array_free_cell(sync_primary_wait_array, index); - sync_array_free_cell(sync_primary_wait_array, index); - #ifdef UNIV_SYNC_DEBUG - mutex_set_debug_info(mutex, file_name, line); + mutex_set_debug_info(mutex, file_name, line); #endif - if (srv_print_latch_waits) { - fprintf(stderr, - "Thread %lu spin wait succeeds at 2:" - " mutex at %p\n", - (ulong) os_thread_pf(os_thread_get_curr_id()), - mutex); - } - - return; +#ifdef UNIV_SRV_PRINT_LATCH_WAITS + fprintf(stderr, "Thread %lu spin wait succeeds at 2:" + " mutex at %p\n", + (ulong) os_thread_pf(os_thread_get_curr_id()), + mutex); +#endif - /* Note that in this case we leave the waiters field - set to 1. We cannot reset it to zero, as we do not know - if there are other waiters. */ - } - } + goto finish_timing; - /* Now we know that there has been some thread holding the mutex - after the change in the wait array and the waiters field was made. - Now there is no risk of infinite wait on the event. */ + /* Note that in this case we leave the waiters field + set to 1. We cannot reset it to zero, as we do not know + if there are other waiters. */ + } + } - if (srv_print_latch_waits) { - fprintf(stderr, - "Thread %lu OS wait mutex at %p cfile %s cline %lu rnds %lu\n", - (ulong) os_thread_pf(os_thread_get_curr_id()), mutex, - mutex->cfile_name, (ulong) mutex->cline, (ulong) i); - } - - mutex_system_call_count++; - mutex_os_wait_count++; + /* Now we know that there has been some thread holding the mutex + after the change in the wait array and the waiters field was made. +Now there is no risk of infinite wait on the event. */ - sync_array_wait_event(sync_primary_wait_array, index); +#ifdef UNIV_SRV_PRINT_LATCH_WAITS + fprintf(stderr, + "Thread %lu OS wait mutex at %p cfile %s cline %lu rnds %lu\n", + (ulong) os_thread_pf(os_thread_get_curr_id()), mutex, + mutex->cfile_name, (ulong) mutex->cline, (ulong) i); +#endif - goto mutex_loop; + mutex_system_call_count++; + mutex_os_wait_count++; + + mutex->count_os_wait++; + + /* + !!!!! Sometimes os_wait can be called without os_thread_yield + */ + + if (timed_mutexes == 1 && timer_started==0) + { + ut_usectime(&sec, &ms); + lstart_time= (ib_longlong)sec * 1000000 + ms; + timer_started = 1; + } + + + sync_array_wait_event(sync_primary_wait_array, index); + goto mutex_loop; + +finish_timing: + if (timed_mutexes == 1 && timer_started==1) + { + ut_usectime(&sec, &ms); + lfinish_time= (ib_longlong)sec * 1000000 + ms; + + ltime_diff= lfinish_time - lstart_time; + mutex->lspent_time += ltime_diff; + if (mutex->lmax_spent_time < ltime_diff) + { + mutex->lmax_spent_time= ltime_diff; + } + } + return; } /********************************************************************** @@ -555,6 +606,7 @@ mutex_set_level( mutex->level = level; } + #ifdef UNIV_SYNC_DEBUG /********************************************************************** Checks that the current thread owns the mutex. Works only in the debug diff --git a/innobase/ut/ut0ut.c b/innobase/ut/ut0ut.c index 732380bcb1f..21c2833b6d6 100644 --- a/innobase/ut/ut0ut.c +++ b/innobase/ut/ut0ut.c @@ -74,6 +74,21 @@ ut_time(void) } /************************************************************** +Returns system time. We do not specify the format of the time returned: +the only way to manipulate it is to use the function ut_difftime. */ + +void +ut_usectime(ulint* sec, ulint* ms) +/*=========*/ +{ + struct timeval tv; + gettimeofday(&tv,NULL); + *sec = (ulint) tv.tv_sec; + *ms = (ulint) tv.tv_usec; + return; +} + +/************************************************************** Returns the difference of two times in seconds. */ double |