summaryrefslogtreecommitdiff
path: root/innobase/sync/sync0sync.c
diff options
context:
space:
mode:
authorvtkachenko@intelp4d.mysql.com <>2004-12-24 12:13:32 +0100
committervtkachenko@intelp4d.mysql.com <>2004-12-24 12:13:32 +0100
commit78846b292369cbf6175baac768edd77183c0809e (patch)
treec26b31d028fae331ef7cf148ca410771f43ef0ef /innobase/sync/sync0sync.c
parent4ba850cab089b7d625bc4fa4fec63c07b35f0692 (diff)
downloadmariadb-git-78846b292369cbf6175baac768edd77183c0809e.tar.gz
logging_ok:
Logging to logging@openlogging.org accepted sql_yacc.yy, sql_parse.cc, sql_lex.h, lex.h: Implements the SHOW MUTEX STATUS command set_var.cc, mysqld.cc, mysql_priv.h: Added new GLOBAL variable timed_mutexes ha_innodb.h: New function innodb_mutex_show_status ha_innodb.cc: Added new innodb variables in SHOW STATUS Implements the SHOW MUTEX STATUS command innodb.test, innodb.result: Added new row_lock_waits status variables tests. variables.test, variables.result: test new variable timed_mutexes ut0ut.c: New function ut_usectime. sync0sync.c: Mutex counting. sync0rw.c: New mutex parameters initialization. srv0srv.c: Counting row lock waits row0sel.c, row0mysql.c: Setting row_lock or table_lock state to thd. que0que.c: Added default no_lock_state to thd. univ.i: Added UNIV_SRV_PRINT_LATCH_WAITS debug define sync0sync.ic: Count mutex using. sync0sync.h: Added new parameters to mutex structure for counting. sync0rw.h: Added new parameters to rw_create_func. srv0srv.h: Added new innodb varuables to SHOW STATUS. que0que.h: Added thread lock states.
Diffstat (limited to 'innobase/sync/sync0sync.c')
-rw-r--r--innobase/sync/sync0sync.c260
1 files changed, 156 insertions, 104 deletions
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