diff options
author | unknown <heikki@donna.mysql.fi> | 2001-10-10 22:47:08 +0300 |
---|---|---|
committer | unknown <heikki@donna.mysql.fi> | 2001-10-10 22:47:08 +0300 |
commit | 1904897be71cba7e6f2cf1192ba0cc2e8d907e00 (patch) | |
tree | fc361924d14a3d1727a8b88f61352ed039054720 /innobase/sync | |
parent | 151ffe886b4b21499471658fdf01ea8347287092 (diff) | |
download | mariadb-git-1904897be71cba7e6f2cf1192ba0cc2e8d907e00.tar.gz |
ut0mem.c Merge changes in InnoDB-3.23.43b
ut0ut.c Merge changes in InnoDB-3.23.43b
trx0purge.c Merge changes in InnoDB-3.23.43b
trx0rec.c Merge changes in InnoDB-3.23.43b
trx0trx.c Merge changes in InnoDB-3.23.43b
trx0undo.c Merge changes in InnoDB-3.23.43b
thr0loc.c Merge changes in InnoDB-3.23.43b
sync0arr.c Merge changes in InnoDB-3.23.43b
sync0rw.c Merge changes in InnoDB-3.23.43b
sync0sync.c Merge changes in InnoDB-3.23.43b
srv0srv.c Merge changes in InnoDB-3.23.43b
srv0start.c Merge changes in InnoDB-3.23.43b
row0ins.c Merge changes in InnoDB-3.23.43b
row0mysql.c Merge changes in InnoDB-3.23.43b
row0purge.c Merge changes in InnoDB-3.23.43b
row0sel.c Merge changes in InnoDB-3.23.43b
row0umod.c Merge changes in InnoDB-3.23.43b
row0upd.c Merge changes in InnoDB-3.23.43b
row0vers.c Merge changes in InnoDB-3.23.43b
rem0cmp.c Merge changes in InnoDB-3.23.43b
que0que.c Merge changes in InnoDB-3.23.43b
pars0opt.c Merge changes in InnoDB-3.23.43b
pars0pars.c Merge changes in InnoDB-3.23.43b
lexyy.c Merge changes in InnoDB-3.23.43b
pars0grm.c Merge changes in InnoDB-3.23.43b
page0page.c Merge changes in InnoDB-3.23.43b
os0file.c Merge changes in InnoDB-3.23.43b
mtr0log.c Merge changes in InnoDB-3.23.43b
mem0pool.c Merge changes in InnoDB-3.23.43b
log0log.c Merge changes in InnoDB-3.23.43b
log0recv.c Merge changes in InnoDB-3.23.43b
lock0lock.c Merge changes in InnoDB-3.23.43b
ibuf0ibuf.c Merge changes in InnoDB-3.23.43b
fil0fil.c Merge changes in InnoDB-3.23.43b
dict0crea.c Merge changes in InnoDB-3.23.43b
dict0dict.c Merge changes in InnoDB-3.23.43b
dict0load.c Merge changes in InnoDB-3.23.43b
dict0mem.c Merge changes in InnoDB-3.23.43b
data0data.c Merge changes in InnoDB-3.23.43b
data0type.c Merge changes in InnoDB-3.23.43b
buf0buf.c Merge changes in InnoDB-3.23.43b
buf0lru.c Merge changes in InnoDB-3.23.43b
btr0btr.c Merge changes in InnoDB-3.23.43b
btr0cur.c Merge changes in InnoDB-3.23.43b
btr0pcur.c Merge changes in InnoDB-3.23.43b
btr0sea.c Merge changes in InnoDB-3.23.43b
data0type.ic Merge changes in InnoDB-3.23.43b
dict0dict.ic Merge changes in InnoDB-3.23.43b
mtr0mtr.ic Merge changes in InnoDB-3.23.43b
row0upd.ic Merge changes in InnoDB-3.23.43b
sync0ipm.ic Merge changes in InnoDB-3.23.43b
sync0rw.ic Merge changes in InnoDB-3.23.43b
sync0sync.ic Merge changes in InnoDB-3.23.43b
trx0rseg.ic Merge changes in InnoDB-3.23.43b
btr0pcur.ic Merge changes in InnoDB-3.23.43b
buf0buf.ic Merge changes in InnoDB-3.23.43b
data0data.ic Merge changes in InnoDB-3.23.43b
row0upd.h Merge changes in InnoDB-3.23.43b
srv0srv.h Merge changes in InnoDB-3.23.43b
sync0arr.h Merge changes in InnoDB-3.23.43b
sync0rw.h Merge changes in InnoDB-3.23.43b
sync0sync.h Merge changes in InnoDB-3.23.43b
trx0trx.h Merge changes in InnoDB-3.23.43b
ut0mem.h Merge changes in InnoDB-3.23.43b
data0data.h Merge changes in InnoDB-3.23.43b
data0type.h Merge changes in InnoDB-3.23.43b
db0err.h Merge changes in InnoDB-3.23.43b
dict0crea.h Merge changes in InnoDB-3.23.43b
dict0dict.h Merge changes in InnoDB-3.23.43b
dict0load.h Merge changes in InnoDB-3.23.43b
dict0mem.h Merge changes in InnoDB-3.23.43b
dict0types.h Merge changes in InnoDB-3.23.43b
fil0fil.h Merge changes in InnoDB-3.23.43b
ibuf0ibuf.h Merge changes in InnoDB-3.23.43b
lock0lock.h Merge changes in InnoDB-3.23.43b
log0log.h Merge changes in InnoDB-3.23.43b
mtr0mtr.h Merge changes in InnoDB-3.23.43b
rem0cmp.h Merge changes in InnoDB-3.23.43b
row0ins.h Merge changes in InnoDB-3.23.43b
row0mysql.h Merge changes in InnoDB-3.23.43b
btr0cur.h Merge changes in InnoDB-3.23.43b
btr0pcur.h Merge changes in InnoDB-3.23.43b
btr0sea.h Merge changes in InnoDB-3.23.43b
buf0buf.h Merge changes in InnoDB-3.23.43b
sql_table.cc Merge changes in InnoDB-3.23.43b
sql_db.cc Merge changes in InnoDB-3.23.43b
ha_innobase.cc Merge changes in InnoDB-3.23.43b
handler.cc Merge changes in InnoDB-3.23.43b
ha_innobase.h Merge changes in InnoDB-3.23.43b
handler.h Merge changes in InnoDB-3.23.43b
sql/ha_innobase.h:
Merge changes in InnoDB-3.23.43b
sql/handler.h:
Merge changes in InnoDB-3.23.43b
sql/ha_innobase.cc:
Merge changes in InnoDB-3.23.43b
sql/handler.cc:
Merge changes in InnoDB-3.23.43b
sql/sql_db.cc:
Merge changes in InnoDB-3.23.43b
sql/sql_table.cc:
Merge changes in InnoDB-3.23.43b
innobase/include/btr0cur.h:
Merge changes in InnoDB-3.23.43b
innobase/include/btr0pcur.h:
Merge changes in InnoDB-3.23.43b
innobase/include/btr0sea.h:
Merge changes in InnoDB-3.23.43b
innobase/include/buf0buf.h:
Merge changes in InnoDB-3.23.43b
innobase/include/data0data.h:
Merge changes in InnoDB-3.23.43b
innobase/include/data0type.h:
Merge changes in InnoDB-3.23.43b
innobase/include/db0err.h:
Merge changes in InnoDB-3.23.43b
innobase/include/dict0crea.h:
Merge changes in InnoDB-3.23.43b
innobase/include/dict0dict.h:
Merge changes in InnoDB-3.23.43b
innobase/include/dict0load.h:
Merge changes in InnoDB-3.23.43b
innobase/include/dict0mem.h:
Merge changes in InnoDB-3.23.43b
innobase/include/dict0types.h:
Merge changes in InnoDB-3.23.43b
innobase/include/fil0fil.h:
Merge changes in InnoDB-3.23.43b
innobase/include/ibuf0ibuf.h:
Merge changes in InnoDB-3.23.43b
innobase/include/lock0lock.h:
Merge changes in InnoDB-3.23.43b
innobase/include/log0log.h:
Merge changes in InnoDB-3.23.43b
innobase/include/mtr0mtr.h:
Merge changes in InnoDB-3.23.43b
innobase/include/rem0cmp.h:
Merge changes in InnoDB-3.23.43b
innobase/include/row0ins.h:
Merge changes in InnoDB-3.23.43b
innobase/include/row0mysql.h:
Merge changes in InnoDB-3.23.43b
innobase/include/row0upd.h:
Merge changes in InnoDB-3.23.43b
innobase/include/srv0srv.h:
Merge changes in InnoDB-3.23.43b
innobase/include/sync0arr.h:
Merge changes in InnoDB-3.23.43b
innobase/include/sync0rw.h:
Merge changes in InnoDB-3.23.43b
innobase/include/sync0sync.h:
Merge changes in InnoDB-3.23.43b
innobase/include/trx0trx.h:
Merge changes in InnoDB-3.23.43b
innobase/include/ut0mem.h:
Merge changes in InnoDB-3.23.43b
innobase/include/btr0pcur.ic:
Merge changes in InnoDB-3.23.43b
innobase/include/buf0buf.ic:
Merge changes in InnoDB-3.23.43b
innobase/include/data0data.ic:
Merge changes in InnoDB-3.23.43b
innobase/include/data0type.ic:
Merge changes in InnoDB-3.23.43b
innobase/include/dict0dict.ic:
Merge changes in InnoDB-3.23.43b
innobase/include/mtr0mtr.ic:
Merge changes in InnoDB-3.23.43b
innobase/include/row0upd.ic:
Merge changes in InnoDB-3.23.43b
innobase/include/sync0ipm.ic:
Merge changes in InnoDB-3.23.43b
innobase/include/sync0rw.ic:
Merge changes in InnoDB-3.23.43b
innobase/include/sync0sync.ic:
Merge changes in InnoDB-3.23.43b
innobase/include/trx0rseg.ic:
Merge changes in InnoDB-3.23.43b
innobase/btr/btr0btr.c:
Merge changes in InnoDB-3.23.43b
innobase/btr/btr0cur.c:
Merge changes in InnoDB-3.23.43b
innobase/btr/btr0pcur.c:
Merge changes in InnoDB-3.23.43b
innobase/btr/btr0sea.c:
Merge changes in InnoDB-3.23.43b
innobase/buf/buf0buf.c:
Merge changes in InnoDB-3.23.43b
innobase/buf/buf0lru.c:
Merge changes in InnoDB-3.23.43b
innobase/data/data0data.c:
Merge changes in InnoDB-3.23.43b
innobase/data/data0type.c:
Merge changes in InnoDB-3.23.43b
innobase/dict/dict0crea.c:
Merge changes in InnoDB-3.23.43b
innobase/dict/dict0dict.c:
Merge changes in InnoDB-3.23.43b
innobase/dict/dict0load.c:
Merge changes in InnoDB-3.23.43b
innobase/dict/dict0mem.c:
Merge changes in InnoDB-3.23.43b
innobase/fil/fil0fil.c:
Merge changes in InnoDB-3.23.43b
innobase/ibuf/ibuf0ibuf.c:
Merge changes in InnoDB-3.23.43b
innobase/lock/lock0lock.c:
Merge changes in InnoDB-3.23.43b
innobase/log/log0log.c:
Merge changes in InnoDB-3.23.43b
innobase/log/log0recv.c:
Merge changes in InnoDB-3.23.43b
innobase/mem/mem0pool.c:
Merge changes in InnoDB-3.23.43b
innobase/mtr/mtr0log.c:
Merge changes in InnoDB-3.23.43b
innobase/os/os0file.c:
Merge changes in InnoDB-3.23.43b
innobase/page/page0page.c:
Merge changes in InnoDB-3.23.43b
innobase/pars/lexyy.c:
Merge changes in InnoDB-3.23.43b
innobase/pars/pars0grm.c:
Merge changes in InnoDB-3.23.43b
innobase/pars/pars0opt.c:
Merge changes in InnoDB-3.23.43b
innobase/pars/pars0pars.c:
Merge changes in InnoDB-3.23.43b
innobase/que/que0que.c:
Merge changes in InnoDB-3.23.43b
innobase/rem/rem0cmp.c:
Merge changes in InnoDB-3.23.43b
innobase/row/row0ins.c:
Merge changes in InnoDB-3.23.43b
innobase/row/row0mysql.c:
Merge changes in InnoDB-3.23.43b
innobase/row/row0purge.c:
Merge changes in InnoDB-3.23.43b
innobase/row/row0sel.c:
Merge changes in InnoDB-3.23.43b
innobase/row/row0umod.c:
Merge changes in InnoDB-3.23.43b
innobase/row/row0upd.c:
Merge changes in InnoDB-3.23.43b
innobase/row/row0vers.c:
Merge changes in InnoDB-3.23.43b
innobase/srv/srv0srv.c:
Merge changes in InnoDB-3.23.43b
innobase/srv/srv0start.c:
Merge changes in InnoDB-3.23.43b
innobase/sync/sync0arr.c:
Merge changes in InnoDB-3.23.43b
innobase/sync/sync0rw.c:
Merge changes in InnoDB-3.23.43b
innobase/sync/sync0sync.c:
Merge changes in InnoDB-3.23.43b
innobase/thr/thr0loc.c:
Merge changes in InnoDB-3.23.43b
innobase/trx/trx0purge.c:
Merge changes in InnoDB-3.23.43b
innobase/trx/trx0rec.c:
Merge changes in InnoDB-3.23.43b
innobase/trx/trx0trx.c:
Merge changes in InnoDB-3.23.43b
innobase/trx/trx0undo.c:
Merge changes in InnoDB-3.23.43b
innobase/ut/ut0mem.c:
Merge changes in InnoDB-3.23.43b
innobase/ut/ut0ut.c:
Merge changes in InnoDB-3.23.43b
BitKeeper/etc/logging_ok:
Logging to logging@openlogging.org accepted
Diffstat (limited to 'innobase/sync')
-rw-r--r-- | innobase/sync/sync0arr.c | 253 | ||||
-rw-r--r-- | innobase/sync/sync0rw.c | 108 | ||||
-rw-r--r-- | innobase/sync/sync0sync.c | 85 |
3 files changed, 293 insertions, 153 deletions
diff --git a/innobase/sync/sync0arr.c b/innobase/sync/sync0arr.c index 4183f3f1c4c..e4c351b9d21 100644 --- a/innobase/sync/sync0arr.c +++ b/innobase/sync/sync0arr.c @@ -14,6 +14,7 @@ Created 9/5/1995 Heikki Tuuri #include "sync0sync.h" #include "sync0rw.h" #include "os0sync.h" +#include "srv0srv.h" /* WAIT ARRAY @@ -64,6 +65,8 @@ struct sync_cell_struct { ibool event_set; /* TRUE if the event is set */ os_event_t event; /* operating system event semaphore handle */ + time_t reservation_time;/* time when the thread reserved + the wait cell */ }; /* NOTE: It is allowed for a thread to wait @@ -321,16 +324,12 @@ sync_array_reserve_cell( sync_array_t* arr, /* in: wait array */ void* object, /* in: pointer to the object to wait for */ ulint type, /* in: lock request type */ - #ifdef UNIV_SYNC_DEBUG - char* file, /* in: in debug version file where - requested */ - ulint line, /* in: in the debug version line where - requested */ - #endif + char* file, /* in: file where requested */ + ulint line, /* in: line where requested */ ulint* index) /* out: index of the reserved cell */ { - ulint i; sync_cell_t* cell; + ulint i; ut_a(object); ut_a(index); @@ -350,18 +349,15 @@ sync_array_reserve_cell( sync_cell_event_reset(cell); } + cell->reservation_time = time(NULL); + cell->thread = os_thread_get_curr_id(); + cell->wait_object = object; cell->request_type = type; - cell->thread = os_thread_get_curr_id(); cell->waiting = FALSE; - #ifdef UNIV_SYNC_DEBUG cell->file = file; cell->line = line; - #else - cell->file = "NOT KNOWN"; - cell->line = 0; - #endif arr->n_reserved++; @@ -436,6 +432,7 @@ static void sync_array_cell_print( /*==================*/ + FILE* file, /* in: file where to print */ sync_cell_t* cell) /* in: sync cell */ { mutex_t* mutex; @@ -445,53 +442,63 @@ sync_array_cell_print( type = cell->request_type; + fprintf(file, +"--Thread %lu has waited at %s line %lu for %.2f seconds the semaphore:\n", + (ulint)cell->thread, cell->file, cell->line, + difftime(time(NULL), cell->reservation_time)); + if (type == SYNC_MUTEX) { - str = "MUTEX ENTER"; mutex = (mutex_t*)cell->wait_object; - printf("Mutex created in file %s line %lu", - mutex->cfile_name, mutex->cline); + fprintf(file, + "Mutex at %lx created file %s line %lu, lock var %lu\n", + (ulint)mutex, mutex->cfile_name, mutex->cline, + mutex->lock_word); + fprintf(file, + "Last time reserved in file %s line %lu, waiters flag %lu\n", + mutex->file_name, mutex->line, mutex->waiters); + } else if (type == RW_LOCK_EX || type == RW_LOCK_SHARED) { if (type == RW_LOCK_EX) { - str = "X-LOCK"; + fprintf(file, "X-lock on"); } else { - str = "S_LOCK"; + fprintf(file, "S-lock on"); } rwlock = (rw_lock_t*)cell->wait_object; - printf("Rw-latch created in file %s line %lu", - rwlock->cfile_name, rwlock->cline); + fprintf(file, " RW-latch at %lx created in file %s line %lu\n", + (ulint)rwlock, rwlock->cfile_name, rwlock->cline); if (rwlock->writer != RW_LOCK_NOT_LOCKED) { - printf(" writer reserved with %lu", rwlock->writer); + fprintf(file, + "a writer (thread id %lu) has reserved it in mode", + (ulint)rwlock->writer_thread); + if (rwlock->writer == RW_LOCK_EX) { + fprintf(file, " exclusive\n"); + } else { + fprintf(file, " wait exclusive\n"); + } } - if (rwlock->writer == RW_LOCK_EX) { - printf(" reserv. thread id %lu", - (ulint)rwlock->writer_thread); - } - - if (rwlock->reader_count > 0) { - printf(" readers %lu", rwlock->reader_count); - } + fprintf(file, "number of readers %lu, waiters flag %lu\n", + rwlock->reader_count, rwlock->waiters); + + fprintf(file, "Last time read locked in file %s line %lu\n", + rwlock->last_s_file_name, rwlock->last_s_line); + fprintf(file, "Last time write locked in file %s line %lu\n", + rwlock->last_x_file_name, rwlock->last_x_line); } else { ut_error; } - printf(" at addr %lx waited for by thread %lu op. %s file %s line %lu ", - (ulint)cell->wait_object, - (ulint)cell->thread, - str, cell->file, cell->line); if (!cell->waiting) { - printf("WAIT ENDED "); + fprintf(file, "wait has ended\n"); } if (cell->event_set) { - printf("EVENT SET"); + fprintf(file, "wait is ending\n"); } - - printf("\n"); } /********************************************************************** @@ -620,14 +627,15 @@ sync_array_detect_deadlock( released the mutex: in this case no deadlock can occur, as the wait array cannot contain a thread with ID_UNDEFINED value. */ + ret = sync_array_deadlock_step(arr, start, thread, 0, - depth); + depth); if (ret) { printf( "Mutex %lx owned by thread %lu file %s line %lu\n", (ulint)mutex, mutex->thread_id, mutex->file_name, mutex->line); - sync_array_cell_print(cell); + sync_array_cell_print(stdout, cell); return(TRUE); } } @@ -636,11 +644,11 @@ sync_array_detect_deadlock( } else if (cell->request_type == RW_LOCK_EX) { - lock = cell->wait_object; + lock = cell->wait_object; - debug = UT_LIST_GET_FIRST(lock->debug_list); + debug = UT_LIST_GET_FIRST(lock->debug_list); - while (debug != NULL) { + while (debug != NULL) { thread = debug->thread_id; @@ -661,23 +669,23 @@ sync_array_detect_deadlock( if (ret) { printf("rw-lock %lx ", (ulint) lock); rw_lock_debug_print(debug); - sync_array_cell_print(cell); + sync_array_cell_print(stdout, cell); return(TRUE); } } debug = UT_LIST_GET_NEXT(list, debug); - } + } - return(FALSE); + return(FALSE); } else if (cell->request_type == RW_LOCK_SHARED) { - lock = cell->wait_object; - debug = UT_LIST_GET_FIRST(lock->debug_list); + lock = cell->wait_object; + debug = UT_LIST_GET_FIRST(lock->debug_list); - while (debug != NULL) { + while (debug != NULL) { thread = debug->thread_id; @@ -694,16 +702,16 @@ sync_array_detect_deadlock( if (ret) { printf("rw-lock %lx ", (ulint) lock); rw_lock_debug_print(debug); - sync_array_cell_print(cell); + sync_array_cell_print(stdout, cell); return(TRUE); } } debug = UT_LIST_GET_NEXT(list, debug); - } + } - return(FALSE); + return(FALSE); } else { ut_error; @@ -714,6 +722,55 @@ sync_array_detect_deadlock( } /********************************************************************** +Determines if we can wake up the thread waiting for a sempahore. */ +static +ibool +sync_arr_cell_can_wake_up( +/*======================*/ + sync_cell_t* cell) /* in: cell to search */ +{ + mutex_t* mutex; + rw_lock_t* lock; + + if (cell->request_type == SYNC_MUTEX) { + + mutex = cell->wait_object; + + if (mutex_get_lock_word(mutex) == 0) { + + return(TRUE); + } + + } else if (cell->request_type == RW_LOCK_EX) { + + lock = cell->wait_object; + + if (rw_lock_get_reader_count(lock) == 0 + && rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) { + + return(TRUE); + } + + if (rw_lock_get_reader_count(lock) == 0 + && rw_lock_get_writer(lock) == RW_LOCK_WAIT_EX + && lock->writer_thread == cell->thread) { + + return(TRUE); + } + + } else if (cell->request_type == RW_LOCK_SHARED) { + lock = cell->wait_object; + + if (rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED) { + + return(TRUE); + } + } + + return(FALSE); +} + +/********************************************************************** Frees the cell. NOTE! sync_array_wait_event frees the cell automatically! */ @@ -740,9 +797,8 @@ sync_array_free_cell( } /************************************************************************** -Looks for the cells in the wait array which refer -to the wait object specified, -and sets their corresponding events to the signaled state. In this +Looks for the cells in the wait array which refer to the wait object +specified, and sets their corresponding events to the signaled state. In this way releases the threads waiting for the object to contend for the object. It is possible that no such cell is found, in which case does nothing. */ @@ -783,6 +839,88 @@ sync_array_signal_object( } /************************************************************************** +If the wakeup algorithm does not work perfectly at semaphore relases, +this function will do the waking (see the comment in mutex_exit). This +function should be called about every 1 second in the server. */ + +void +sync_arr_wake_threads_if_sema_free(void) +/*====================================*/ +{ + sync_array_t* arr = sync_primary_wait_array; + sync_cell_t* cell; + ulint count; + ulint i; + + sync_array_enter(arr); + + i = 0; + count = 0; + + while (count < arr->n_reserved) { + + cell = sync_array_get_nth_cell(arr, i); + + if (cell->wait_object != NULL) { + + count++; + + if (sync_arr_cell_can_wake_up(cell)) { + + sync_cell_event_set(cell); + } + } + + i++; + } + + sync_array_exit(arr); +} + +/************************************************************************** +Prints warnings of long semaphore waits to stderr. Currently > 120 sec. */ + +void +sync_array_print_long_waits(void) +/*=============================*/ +{ + sync_cell_t* cell; + ibool old_val; + ibool noticed = FALSE; + ulint i; + + for (i = 0; i < sync_primary_wait_array->n_cells; i++) { + + cell = sync_array_get_nth_cell(sync_primary_wait_array, i); + + if (cell->wait_object != NULL + && difftime(time(NULL), cell->reservation_time) > 120) { + + fprintf(stderr, + "InnoDB: Warning: a long semaphore wait:\n"); + sync_array_cell_print(stderr, cell); + + noticed = TRUE; + } + } + + if (noticed) { + fprintf(stderr, +"InnoDB: ###### Starts InnoDB Monitor for 30 secs to print diagnostic info:\n"); + old_val = srv_print_innodb_monitor; + + srv_print_innodb_monitor = TRUE; + os_event_set(srv_lock_timeout_thread_event); + + os_thread_sleep(30000000); + + srv_print_innodb_monitor = old_val; + fprintf(stderr, +"InnoDB: ###### Diagnostic info printed to the standard output\n"); + } +} + +/************************************************************************** Prints info of the wait array. */ static void @@ -795,9 +933,8 @@ sync_array_output_info( ulint count; ulint i; - printf("-----------------------------------------------------\n"); - printf("SYNC ARRAY INFO: reservation count %ld, signal count %ld\n", - arr->res_count, arr->sg_count); + printf("OS WAIT ARRAY INFO: reservation count %ld, signal count %ld\n", + arr->res_count, arr->sg_count); i = 0; count = 0; @@ -807,7 +944,7 @@ sync_array_output_info( if (cell->wait_object != NULL) { count++; - sync_array_cell_print(cell); + sync_array_cell_print(stdout, cell); } i++; diff --git a/innobase/sync/sync0rw.c b/innobase/sync/sync0rw.c index dc49ce2197e..1ef2920618f 100644 --- a/innobase/sync/sync0rw.c +++ b/innobase/sync/sync0rw.c @@ -17,11 +17,13 @@ Created 9/11/1995 Heikki Tuuri ulint rw_s_system_call_count = 0; ulint rw_s_spin_wait_count = 0; +ulint rw_s_os_wait_count = 0; ulint rw_s_exit_count = 0; ulint rw_x_system_call_count = 0; ulint rw_x_spin_wait_count = 0; +ulint rw_x_os_wait_count = 0; ulint rw_x_exit_count = 0; @@ -95,8 +97,7 @@ rw_lock_create_func( mutex_create(rw_lock_get_mutex(lock)); mutex_set_level(rw_lock_get_mutex(lock), SYNC_NO_ORDER_CHECK); - ut_memcpy(&(lock->mutex.cfile_name), cfile_name, - ut_min(RW_CNAME_LEN - 1, ut_strlen(cfile_name))); + lock->mutex.cfile_name = cfile_name; lock->mutex.cline = cline; rw_lock_set_waiters(lock, 0); @@ -111,11 +112,14 @@ rw_lock_create_func( lock->magic_n = RW_LOCK_MAGIC_N; lock->level = SYNC_LEVEL_NONE; - ut_memcpy(&(lock->cfile_name), cfile_name, - ut_min(RW_CNAME_LEN - 1, ut_strlen(cfile_name))); - lock->cfile_name[RW_CNAME_LEN - 1] = '\0'; + lock->cfile_name = cfile_name; lock->cline = cline; + lock->last_s_file_name = "not yet reserved"; + lock->last_x_file_name = "not yet reserved"; + lock->last_s_line = 0; + lock->last_x_line = 0; + mutex_enter(&rw_lock_list_mutex); UT_LIST_ADD_FIRST(list, rw_lock_list, lock); @@ -186,14 +190,11 @@ for the lock, before suspending the thread. */ void rw_lock_s_lock_spin( /*================*/ - rw_lock_t* lock /* in: pointer to rw-lock */ - #ifdef UNIV_SYNC_DEBUG - ,ulint pass, /* in: pass value; != 0, if the lock + rw_lock_t* lock, /* in: pointer to rw-lock */ + ulint pass, /* in: pass value; != 0, if the lock will be passed to another thread to unlock */ char* file_name, /* in: file name where lock requested */ - ulint line /* in: line where requested */ - #endif -) + ulint line) /* in: line where requested */ { ulint index; /* index of the reserved wait cell */ ulint i; /* spin round count */ @@ -203,7 +204,7 @@ rw_lock_s_lock_spin( lock_loop: rw_s_spin_wait_count++; - /* Spin waiting for the writer field to become free */ + /* Spin waiting for the writer field to become free */ i = 0; while (rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED @@ -223,19 +224,14 @@ lock_loop: printf( "Thread %lu spin wait rw-s-lock at %lx cfile %s cline %lu rnds %lu\n", os_thread_get_curr_id(), (ulint)lock, - &(lock->cfile_name), lock->cline, i); + lock->cfile_name, lock->cline, i); } mutex_enter(rw_lock_get_mutex(lock)); /* We try once again to obtain the lock */ - if (TRUE == rw_lock_s_lock_low(lock - #ifdef UNIV_SYNC_DEBUG - , pass, file_name, - line - #endif - )) { + if (TRUE == rw_lock_s_lock_low(lock, pass, file_name, line)) { mutex_exit(rw_lock_get_mutex(lock)); return; /* Success */ @@ -247,9 +243,7 @@ lock_loop: sync_array_reserve_cell(sync_primary_wait_array, lock, RW_LOCK_SHARED, - #ifdef UNIV_SYNC_DEBUG file_name, line, - #endif &index); rw_lock_set_waiters(lock, 1); @@ -260,12 +254,13 @@ lock_loop: printf( "Thread %lu OS wait rw-s-lock at %lx cfile %s cline %lu\n", os_thread_get_curr_id(), (ulint)lock, - &(lock->cfile_name), lock->cline); + lock->cfile_name, lock->cline); } rw_s_system_call_count++; + rw_s_os_wait_count++; - sync_array_wait_event(sync_primary_wait_array, index); + sync_array_wait_event(sync_primary_wait_array, index); goto lock_loop; } @@ -307,13 +302,10 @@ rw_lock_x_lock_low( not succeed, RW_LOCK_EX if success, RW_LOCK_WAIT_EX, if got wait reservation */ rw_lock_t* lock, /* in: pointer to rw-lock */ - ulint pass /* in: pass value; != 0, if the lock will + ulint pass, /* in: pass value; != 0, if the lock will be passed to another thread to unlock */ - #ifdef UNIV_SYNC_DEBUG - ,char* file_name, /* in: file name where lock requested */ - ulint line /* in: line where requested */ - #endif -) + char* file_name,/* in: file name where lock requested */ + ulint line) /* in: line where requested */ { ut_ad(mutex_own(rw_lock_get_mutex(lock))); @@ -330,6 +322,8 @@ rw_lock_x_lock_low( rw_lock_add_debug_info(lock, pass, RW_LOCK_EX, file_name, line); #endif + lock->last_x_file_name = file_name; + lock->last_x_line = line; /* Locking succeeded, we may return */ return(RW_LOCK_EX); @@ -364,6 +358,9 @@ rw_lock_x_lock_low( file_name, line); #endif + lock->last_x_file_name = file_name; + lock->last_x_line = line; + /* Locking succeeded, we may return */ return(RW_LOCK_EX); } @@ -382,6 +379,9 @@ rw_lock_x_lock_low( line); #endif + lock->last_x_file_name = file_name; + lock->last_x_line = line; + /* Locking succeeded, we may return */ return(RW_LOCK_EX); } @@ -404,13 +404,10 @@ void rw_lock_x_lock_func( /*================*/ rw_lock_t* lock, /* in: pointer to rw-lock */ - ulint pass /* in: pass value; != 0, if the lock will + ulint pass, /* in: pass value; != 0, if the lock will be passed to another thread to unlock */ - #ifdef UNIV_SYNC_DEBUG - ,char* file_name, /* in: file name where lock requested */ - ulint line /* in: line where requested */ - #endif -) + char* file_name,/* in: file name where lock requested */ + ulint line) /* in: line where requested */ { ulint index; /* index of the reserved wait cell */ ulint state; /* lock state acquired */ @@ -422,11 +419,7 @@ lock_loop: /* Acquire the mutex protecting the rw-lock fields */ mutex_enter_fast(&(lock->mutex)); - state = rw_lock_x_lock_low(lock, pass - #ifdef UNIV_SYNC_DEBUG - ,file_name, line - #endif - ); + state = rw_lock_x_lock_low(lock, pass, file_name, line); mutex_exit(&(lock->mutex)); @@ -469,6 +462,7 @@ lock_loop: os_thread_yield(); } } else { + i = 0; /* Eliminate a compiler warning */ ut_error; } @@ -476,7 +470,7 @@ lock_loop: printf( "Thread %lu spin wait rw-x-lock at %lx cfile %s cline %lu rnds %lu\n", os_thread_get_curr_id(), (ulint)lock, - &(lock->cfile_name), lock->cline, i); + lock->cfile_name, lock->cline, i); } rw_x_spin_wait_count++; @@ -486,11 +480,7 @@ lock_loop: mutex_enter(rw_lock_get_mutex(lock)); - state = rw_lock_x_lock_low(lock, pass - #ifdef UNIV_SYNC_DEBUG - ,file_name, line - #endif - ); + state = rw_lock_x_lock_low(lock, pass, file_name, line); if (state == RW_LOCK_EX) { mutex_exit(rw_lock_get_mutex(lock)); @@ -502,9 +492,7 @@ lock_loop: sync_array_reserve_cell(sync_primary_wait_array, lock, RW_LOCK_EX, - #ifdef UNIV_SYNC_DEBUG file_name, line, - #endif &index); rw_lock_set_waiters(lock, 1); @@ -514,11 +502,12 @@ lock_loop: if (srv_print_latch_waits) { printf( "Thread %lu OS wait for rw-x-lock at %lx cfile %s cline %lu\n", - os_thread_get_curr_id(), (ulint)lock, &(lock->cfile_name), + os_thread_get_curr_id(), (ulint)lock, lock->cfile_name, lock->cline); } rw_x_system_call_count++; + rw_x_os_wait_count++; sync_array_wait_event(sync_primary_wait_array, index); @@ -537,8 +526,8 @@ rw_lock_debug_mutex_enter(void) /*==========================*/ { loop: - if (0 == mutex_enter_nowait(&rw_lock_debug_mutex)) { - + if (0 == mutex_enter_nowait(&rw_lock_debug_mutex, + IB__FILE__, __LINE__)) { return; } @@ -546,8 +535,8 @@ loop: rw_lock_debug_waiters = TRUE; - if (0 == mutex_enter_nowait(&rw_lock_debug_mutex)) { - + if (0 == mutex_enter_nowait(&rw_lock_debug_mutex, + IB__FILE__, __LINE__)) { return; } @@ -747,8 +736,6 @@ rw_lock_list_print_info(void) /*=========================*/ { #ifndef UNIV_SYNC_DEBUG - printf( - "Sorry, cannot give rw-lock list info in non-debug version!\n"); #else rw_lock_t* lock; ulint count = 0; @@ -756,8 +743,9 @@ rw_lock_list_print_info(void) mutex_enter(&rw_lock_list_mutex); - printf("----------------------------------------------\n"); - printf("RW-LOCK INFO\n"); + printf("-------------\n"); + printf("RW-LATCH INFO\n"); + printf("-------------\n"); lock = UT_LIST_GET_FIRST(rw_lock_list); @@ -810,9 +798,9 @@ rw_lock_print( ulint count = 0; rw_lock_debug_t* info; - printf("-------------------------------------------------\n"); - printf("RW-LOCK INFO\n"); - printf("RW-LOCK: %lx ", (ulint)lock); + printf("-------------\n"); + printf("RW-LATCH INFO\n"); + printf("RW-LATCH: %lx ", (ulint)lock); if ((rw_lock_get_writer(lock) != RW_LOCK_NOT_LOCKED) || (rw_lock_get_reader_count(lock) != 0) diff --git a/innobase/sync/sync0sync.c b/innobase/sync/sync0sync.c index f0dbe145098..8b2a39e15eb 100644 --- a/innobase/sync/sync0sync.c +++ b/innobase/sync/sync0sync.c @@ -119,6 +119,7 @@ ulint mutex_system_call_count = 0; ulint mutex_spin_round_count = 0; ulint mutex_spin_wait_count = 0; +ulint mutex_os_wait_count = 0; ulint mutex_exit_count = 0; /* The global array of wait cells for implementation of the database's own @@ -228,12 +229,10 @@ mutex_create_func( mutex_set_waiters(mutex, 0); mutex->magic_n = MUTEX_MAGIC_N; mutex->line = 0; - mutex->file_name = "FILE NOT KNOWN"; + mutex->file_name = "not yet reserved"; mutex->thread_id = ULINT_UNDEFINED; mutex->level = SYNC_LEVEL_NONE; - ut_memcpy(&(mutex->cfile_name), cfile_name, - ut_min(MUTEX_CNAME_LEN - 1, ut_strlen(cfile_name))); - mutex->cfile_name[MUTEX_CNAME_LEN - 1] = '\0'; + mutex->cfile_name = cfile_name; mutex->cline = cline; /* Check that lock_word is aligned; this is important on Intel */ @@ -291,17 +290,23 @@ immediately, returns with return value 1. */ ulint mutex_enter_nowait( /*===============*/ - /* out: 0 if succeed, 1 if not */ - mutex_t* mutex) /* in: pointer to mutex */ + /* out: 0 if succeed, 1 if not */ + mutex_t* mutex, /* in: pointer to mutex */ + char* file_name, /* in: file name where mutex + requested */ + ulint line) /* in: line where requested */ { ut_ad(mutex_validate(mutex)); if (!mutex_test_and_set(mutex)) { #ifdef UNIV_SYNC_DEBUG - mutex_set_debug_info(mutex, IB__FILE__, __LINE__); + mutex_set_debug_info(mutex, file_name, line); #endif + mutex->file_name = file_name; + mutex->line = line; + return(0); /* Succeeded! */ } @@ -349,13 +354,9 @@ for the mutex before suspending the thread. */ void mutex_spin_wait( /*============*/ - mutex_t* mutex /* in: pointer to mutex */ - - #ifdef UNIV_SYNC_DEBUG - ,char* file_name, /* in: file name where mutex requested */ - ulint line /* in: line where requested */ - #endif -) + mutex_t* mutex, /* in: pointer to mutex */ + 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 */ @@ -391,7 +392,7 @@ spin_loop: if (srv_print_latch_waits) { printf( "Thread %lu spin wait mutex at %lx cfile %s cline %lu rnds %lu\n", - os_thread_get_curr_id(), (ulint)mutex, &(mutex->cfile_name), + os_thread_get_curr_id(), (ulint)mutex, mutex->cfile_name, mutex->cline, i); } @@ -404,6 +405,9 @@ spin_loop: mutex_set_debug_info(mutex, file_name, line); #endif + mutex->file_name = file_name; + mutex->line = line; + return; } @@ -423,9 +427,7 @@ spin_loop: sync_array_reserve_cell(sync_primary_wait_array, mutex, SYNC_MUTEX, - #ifdef UNIV_SYNC_DEBUG file_name, line, - #endif &index); mutex_system_call_count++; @@ -438,7 +440,9 @@ spin_loop: mutex_set_waiters(mutex, 1); - 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 */ @@ -448,6 +452,9 @@ spin_loop: mutex_set_debug_info(mutex, file_name, line); #endif + mutex->file_name = file_name; + mutex->line = line; + if (srv_print_latch_waits) { printf( "Thread %lu spin wait succeeds at 2: mutex at %lx\n", @@ -459,6 +466,7 @@ spin_loop: /* 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. */ + } } /* Now we know that there has been some thread holding the mutex @@ -468,11 +476,13 @@ spin_loop: if (srv_print_latch_waits) { printf( "Thread %lu OS wait mutex at %lx cfile %s cline %lu rnds %lu\n", - os_thread_get_curr_id(), (ulint)mutex, &(mutex->cfile_name), + os_thread_get_curr_id(), (ulint)mutex, mutex->cfile_name, mutex->cline, i); } mutex_system_call_count++; + mutex_os_wait_count++; + sync_array_wait_event(sync_primary_wait_array, index); goto mutex_loop; @@ -578,7 +588,6 @@ mutex_list_print_info(void) /*=======================*/ { #ifndef UNIV_SYNC_DEBUG - printf("Sorry, cannot give mutex list info in non-debug version!\n"); #else mutex_t* mutex; char* file_name; @@ -586,8 +595,9 @@ mutex_list_print_info(void) os_thread_id_t thread_id; ulint count = 0; - printf("-----------------------------------------------\n"); + printf("----------\n"); printf("MUTEX INFO\n"); + printf("----------\n"); mutex_enter(&mutex_list_mutex); @@ -597,10 +607,10 @@ mutex_list_print_info(void) count++; if (mutex_get_lock_word(mutex) != 0) { - - mutex_get_debug_info(mutex, &file_name, &line, &thread_id); - - printf("Locked mutex: addr %lx thread %ld file %s line %ld\n", + mutex_get_debug_info(mutex, &file_name, &line, + &thread_id); + printf( + "Locked mutex: addr %lx thread %ld file %s line %ld\n", (ulint)mutex, thread_id, file_name, line); } @@ -791,7 +801,7 @@ sync_thread_levels_g( limit, slot->level); if (mutex->magic_n == MUTEX_MAGIC_N) { - printf("Mutex created at %s %lu\n", &(mutex->cfile_name), + printf("Mutex created at %s %lu\n", mutex->cfile_name, mutex->cline); if (mutex_get_lock_word(mutex) != 0) { @@ -890,6 +900,7 @@ sync_thread_levels_empty_gen( if (slot->latch != NULL && (!dict_mutex_allowed || (slot->level != SYNC_DICT + && slot->level != SYNC_FOREIGN_KEY_CHECK && slot->level != SYNC_PURGE_IS_RUNNING))) { lock = slot->latch; @@ -993,6 +1004,8 @@ sync_thread_add_level( ut_a(sync_thread_levels_g(array, SYNC_RECV)); } else if (level == SYNC_LOG) { ut_a(sync_thread_levels_g(array, SYNC_LOG)); + } else if (level == SYNC_THR_LOCAL) { + ut_a(sync_thread_levels_g(array, SYNC_THR_LOCAL)); } else if (level == SYNC_ANY_LATCH) { ut_a(sync_thread_levels_g(array, SYNC_ANY_LATCH)); } else if (level == SYNC_TRX_SYS_HEADER) { @@ -1071,6 +1084,8 @@ sync_thread_add_level( SYNC_IBUF_PESS_INSERT_MUTEX)); } else if (level == SYNC_DICT_AUTOINC_MUTEX) { ut_a(sync_thread_levels_g(array, SYNC_DICT_AUTOINC_MUTEX)); + } else if (level == SYNC_FOREIGN_KEY_CHECK) { + ut_a(sync_thread_levels_g(array, SYNC_FOREIGN_KEY_CHECK)); } else if (level == SYNC_DICT_HEADER) { ut_a(sync_thread_levels_g(array, SYNC_DICT_HEADER)); } else if (level == SYNC_PURGE_IS_RUNNING) { @@ -1231,15 +1246,17 @@ void sync_print_wait_info(void) /*======================*/ { +#ifdef UNIV_SYNC_DEBUG + printf("Mutex exits %lu, rws exits %lu, rwx exits %lu\n", + mutex_exit_count, rw_s_exit_count, rw_x_exit_count); +#endif printf( - "Mut ex %lu sp %lu r %lu sys %lu; rws %lu %lu %lu; rwx %lu %lu %lu\n", - mutex_exit_count, +"Mutex spin waits %lu, rounds %lu, OS waits %lu\n" +"RW-shared spins %lu, OS waits %lu; RW-excl spins %lu, OS waits %lu\n", mutex_spin_wait_count, mutex_spin_round_count, - mutex_system_call_count, - rw_s_exit_count, - rw_s_spin_wait_count, rw_s_system_call_count, - rw_x_exit_count, - rw_x_spin_wait_count, rw_x_system_call_count); + mutex_os_wait_count, + rw_s_spin_wait_count, rw_s_os_wait_count, + rw_x_spin_wait_count, rw_x_os_wait_count); } /*********************************************************************** @@ -1249,10 +1266,8 @@ void sync_print(void) /*============*/ { - printf("SYNC INFO:\n"); mutex_list_print_info(); rw_lock_list_print_info(); sync_array_print_info(sync_primary_wait_array); sync_print_wait_info(); - printf("-----------------------------------------------------\n"); } |