summaryrefslogtreecommitdiff
path: root/innobase/sync
diff options
context:
space:
mode:
authorunknown <heikki@donna.mysql.fi>2001-10-10 22:47:08 +0300
committerunknown <heikki@donna.mysql.fi>2001-10-10 22:47:08 +0300
commit1904897be71cba7e6f2cf1192ba0cc2e8d907e00 (patch)
treefc361924d14a3d1727a8b88f61352ed039054720 /innobase/sync
parent151ffe886b4b21499471658fdf01ea8347287092 (diff)
downloadmariadb-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.c253
-rw-r--r--innobase/sync/sync0rw.c108
-rw-r--r--innobase/sync/sync0sync.c85
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");
}