summaryrefslogtreecommitdiff
path: root/innobase/sync
diff options
context:
space:
mode:
authortsmith@quadxeon.mysql.com <>2006-11-09 05:02:37 +0100
committertsmith@quadxeon.mysql.com <>2006-11-09 05:02:37 +0100
commitf1e0cf9d285269571e96ac4fc058e7494a69c7c7 (patch)
tree03d4d71d67b4aaee305c7431903f593ad5229733 /innobase/sync
parent41117b1226bcb02536bf963d9a18a6140d5ffe1a (diff)
downloadmariadb-git-f1e0cf9d285269571e96ac4fc058e7494a69c7c7.tar.gz
This ChangeSet must be null-merged to 5.1. Applied innodb-5.0-ss982, -ss998, -ss1003
Fixes: - Bug #15815: Very poor performance with multiple queries running concurrently - Bug #22868: 'Thread thrashing' with > 50 concurrent conns under an upd-intensive workloadw - Bug #23769: Debug assertion failure with innodb_locks_unsafe_for_binlog - Bug #24089: Race condition in fil_flush_file_spaces()
Diffstat (limited to 'innobase/sync')
-rw-r--r--innobase/sync/sync0arr.c119
-rw-r--r--innobase/sync/sync0rw.c2
-rw-r--r--innobase/sync/sync0sync.c8
3 files changed, 49 insertions, 80 deletions
diff --git a/innobase/sync/sync0arr.c b/innobase/sync/sync0arr.c
index 198ef49ca9f..64f9310bad3 100644
--- a/innobase/sync/sync0arr.c
+++ b/innobase/sync/sync0arr.c
@@ -62,9 +62,6 @@ struct sync_cell_struct {
ibool waiting; /* TRUE if the thread has already
called sync_array_event_wait
on this cell */
- 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 */
};
@@ -218,10 +215,7 @@ sync_array_create(
for (i = 0; i < n_cells; i++) {
cell = sync_array_get_nth_cell(arr, i);
cell->wait_object = NULL;
-
- /* Create an operating system event semaphore with no name */
- cell->event = os_event_create(NULL);
- cell->event_set = FALSE; /* it is created in reset state */
+ cell->waiting = FALSE;
}
return(arr);
@@ -235,19 +229,12 @@ sync_array_free(
/*============*/
sync_array_t* arr) /* in, own: sync wait array */
{
- ulint i;
- sync_cell_t* cell;
ulint protection;
ut_a(arr->n_reserved == 0);
sync_array_validate(arr);
- for (i = 0; i < arr->n_cells; i++) {
- cell = sync_array_get_nth_cell(arr, i);
- os_event_free(cell->event);
- }
-
protection = arr->protection;
/* Release the mutex protecting the wait array complex */
@@ -293,27 +280,19 @@ sync_array_validate(
}
/***********************************************************************
-Puts the cell event in set state. */
-static
-void
-sync_cell_event_set(
-/*================*/
- sync_cell_t* cell) /* in: array cell */
-{
- os_event_set(cell->event);
- cell->event_set = TRUE;
-}
-
-/***********************************************************************
Puts the cell event in reset state. */
static
void
sync_cell_event_reset(
/*==================*/
- sync_cell_t* cell) /* in: array cell */
+ ulint type, /* in: lock type mutex/rw_lock */
+ void* object) /* in: the rw_lock/mutex object */
{
- os_event_reset(cell->event);
- cell->event_set = FALSE;
+ if (type == SYNC_MUTEX) {
+ os_event_reset(((mutex_t *) object)->event);
+ } else {
+ os_event_reset(((rw_lock_t *) object)->event);
+ }
}
/**********************************************************************
@@ -346,14 +325,7 @@ sync_array_reserve_cell(
if (cell->wait_object == NULL) {
- /* Make sure the event is reset */
- if (cell->event_set) {
- sync_cell_event_reset(cell);
- }
-
- cell->reservation_time = time(NULL);
- cell->thread = os_thread_get_curr_id();
-
+ cell->waiting = FALSE;
cell->wait_object = object;
if (type == SYNC_MUTEX) {
@@ -363,7 +335,6 @@ sync_array_reserve_cell(
}
cell->request_type = type;
- cell->waiting = FALSE;
cell->file = file;
cell->line = line;
@@ -373,6 +344,13 @@ sync_array_reserve_cell(
*index = i;
sync_array_exit(arr);
+
+ /* Make sure the event is reset */
+ sync_cell_event_reset(type, object);
+
+ cell->reservation_time = time(NULL);
+
+ cell->thread = os_thread_get_curr_id();
return;
}
@@ -408,7 +386,12 @@ sync_array_wait_event(
ut_a(!cell->waiting);
ut_ad(os_thread_get_curr_id() == cell->thread);
- event = cell->event;
+ if (cell->request_type == SYNC_MUTEX) {
+ event = ((mutex_t*) cell->wait_object)->event;
+ } else {
+ event = ((rw_lock_t*) cell->wait_object)->event;
+ }
+
cell->waiting = TRUE;
#ifdef UNIV_SYNC_DEBUG
@@ -510,10 +493,6 @@ sync_array_cell_print(
if (!cell->waiting) {
fputs("wait has ended\n", file);
}
-
- if (cell->event_set) {
- fputs("wait is ending\n", file);
- }
}
#ifdef UNIV_SYNC_DEBUG
@@ -623,7 +602,7 @@ sync_array_detect_deadlock(
depth++;
- if (cell->event_set || !cell->waiting) {
+ if (!cell->waiting) {
return(FALSE); /* No deadlock here */
}
@@ -802,6 +781,7 @@ sync_array_free_cell(
ut_a(cell->wait_object != NULL);
+ cell->waiting = FALSE;
cell->wait_object = NULL;
ut_a(arr->n_reserved > 0);
@@ -811,44 +791,17 @@ 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
-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. */
+Increments the signalled count. */
void
-sync_array_signal_object(
-/*=====================*/
- sync_array_t* arr, /* in: wait array */
- void* object) /* in: wait object */
+sync_array_object_signalled(
+/*========================*/
+ sync_array_t* arr) /* in: wait array */
{
- sync_cell_t* cell;
- ulint count;
- ulint i;
-
sync_array_enter(arr);
arr->sg_count++;
- i = 0;
- count = 0;
-
- while (count < arr->n_reserved) {
-
- cell = sync_array_get_nth_cell(arr, i);
-
- if (cell->wait_object != NULL) {
-
- count++;
- if (cell->wait_object == object) {
-
- sync_cell_event_set(cell);
- }
- }
-
- i++;
- }
-
sync_array_exit(arr);
}
@@ -881,7 +834,17 @@ sync_arr_wake_threads_if_sema_free(void)
if (sync_arr_cell_can_wake_up(cell)) {
- sync_cell_event_set(cell);
+ if (cell->request_type == SYNC_MUTEX) {
+ mutex_t* mutex;
+
+ mutex = cell->wait_object;
+ os_event_set(mutex->event);
+ } else {
+ rw_lock_t* lock;
+
+ lock = cell->wait_object;
+ os_event_set(lock->event);
+ }
}
}
@@ -911,7 +874,7 @@ sync_array_print_long_waits(void)
cell = sync_array_get_nth_cell(sync_primary_wait_array, i);
- if (cell->wait_object != NULL
+ if (cell->wait_object != NULL && cell->waiting
&& difftime(time(NULL), cell->reservation_time) > 240) {
fputs("InnoDB: Warning: a long semaphore wait:\n",
stderr);
@@ -919,7 +882,7 @@ sync_array_print_long_waits(void)
noticed = TRUE;
}
- if (cell->wait_object != NULL
+ if (cell->wait_object != NULL && cell->waiting
&& difftime(time(NULL), cell->reservation_time)
> fatal_timeout) {
fatal = TRUE;
diff --git a/innobase/sync/sync0rw.c b/innobase/sync/sync0rw.c
index 973b46fdd50..050de73db9e 100644
--- a/innobase/sync/sync0rw.c
+++ b/innobase/sync/sync0rw.c
@@ -128,6 +128,7 @@ rw_lock_create_func(
lock->last_x_file_name = "not yet reserved";
lock->last_s_line = 0;
lock->last_x_line = 0;
+ lock->event = os_event_create(NULL);
mutex_enter(&rw_lock_list_mutex);
@@ -163,6 +164,7 @@ rw_lock_free(
mutex_free(rw_lock_get_mutex(lock));
mutex_enter(&rw_lock_list_mutex);
+ os_event_free(lock->event);
if (UT_LIST_GET_PREV(list, lock)) {
ut_a(UT_LIST_GET_PREV(list, lock)->magic_n == RW_LOCK_MAGIC_N);
diff --git a/innobase/sync/sync0sync.c b/innobase/sync/sync0sync.c
index 43249f4b96f..95bf83dce79 100644
--- a/innobase/sync/sync0sync.c
+++ b/innobase/sync/sync0sync.c
@@ -212,6 +212,7 @@ mutex_create_func(
os_fast_mutex_init(&(mutex->os_fast_mutex));
mutex->lock_word = 0;
#endif
+ mutex->event = os_event_create(NULL);
mutex_set_waiters(mutex, 0);
mutex->magic_n = MUTEX_MAGIC_N;
#ifdef UNIV_SYNC_DEBUG
@@ -288,6 +289,8 @@ mutex_free(
mutex_exit(&mutex_list_mutex);
}
+ os_event_free(mutex->event);
+
#if !defined(_WIN32) || !defined(UNIV_CAN_USE_X86_ASSEMBLER)
os_fast_mutex_free(&(mutex->os_fast_mutex));
#endif
@@ -564,8 +567,8 @@ mutex_signal_object(
/* The memory order of resetting the waiters field and
signaling the object is important. See LEMMA 1 above. */
-
- sync_array_signal_object(sync_primary_wait_array, mutex);
+ os_event_set(mutex->event);
+ sync_array_object_signalled(sync_primary_wait_array);
}
#ifdef UNIV_SYNC_DEBUG
@@ -1114,6 +1117,7 @@ sync_thread_add_level(
ut_a(sync_thread_levels_g(array, SYNC_PURGE_SYS));
} else if (level == SYNC_TREE_NODE) {
ut_a(sync_thread_levels_contain(array, SYNC_INDEX_TREE)
+ || sync_thread_levels_contain(array, SYNC_DICT_OPERATION)
|| sync_thread_levels_g(array, SYNC_TREE_NODE - 1));
} else if (level == SYNC_TREE_NODE_FROM_HASH) {
ut_a(1);