Commit 61cc8392 authored by Mikael Ronstrom's avatar Mikael Ronstrom

Fix for Percona reported bug with manual merge and fix of bug in

patch (changed to use of UNIV_SYNC_ATOMIC from faulty HAVE_ATOMIC_BUILTINS).
parent d575f6ce
...@@ -57,10 +57,25 @@ UNIV_INLINE ...@@ -57,10 +57,25 @@ UNIV_INLINE
void void
rw_lock_set_waiters( rw_lock_set_waiters(
/*================*/ /*================*/
rw_lock_t* lock, rw_lock_t* lock)
ulint flag)
{ {
lock->waiters = flag; #ifdef UNIV_SYNC_ATOMIC
os_compare_and_swap(&(lock->waiters), 0, 1);
#else /* UNIV_SYNC_ATOMIC */
lock->waiters = 1;
#endif /* UNIV_SYNC_ATOMIC */
}
UNIV_INLINE
void
rw_lock_reset_waiters(
/*================*/
rw_lock_t* lock)
{
#ifdef UNIV_SYNC_ATOMIC
os_compare_and_swap(&(lock->waiters), 1, 0);
#else /* UNIV_SYNC_ATOMIC */
lock->waiters = 0;
#endif /* UNIV_SYNC_ATOMIC */
} }
/********************************************************************** /**********************************************************************
...@@ -454,7 +469,7 @@ rw_lock_s_unlock_direct( ...@@ -454,7 +469,7 @@ rw_lock_s_unlock_direct(
/* Decrease reader count by incrementing lock_word */ /* Decrease reader count by incrementing lock_word */
lock->lock_word++; lock->lock_word++;
ut_ad(!lock->waiters); ut_ad(!rw_lock_get_waiters(lock));
ut_ad(rw_lock_validate(lock)); ut_ad(rw_lock_validate(lock));
#ifdef UNIV_SYNC_PERF_STAT #ifdef UNIV_SYNC_PERF_STAT
rw_s_exit_count++; rw_s_exit_count++;
...@@ -494,8 +509,8 @@ rw_lock_x_unlock_func( ...@@ -494,8 +509,8 @@ rw_lock_x_unlock_func(
/* Lock is now free. May have to signal read/write waiters. /* Lock is now free. May have to signal read/write waiters.
We do not need to signal wait_ex waiters, since they cannot We do not need to signal wait_ex waiters, since they cannot
exist when there is a writer. */ exist when there is a writer. */
if(lock->waiters) { if(rw_lock_get_waiters(lock)) {
rw_lock_set_waiters(lock, 0); rw_lock_reset_waiters(lock);
os_event_set(lock->event); os_event_set(lock->event);
sync_array_object_signalled(sync_primary_wait_array); sync_array_object_signalled(sync_primary_wait_array);
} }
...@@ -532,7 +547,7 @@ rw_lock_x_unlock_direct( ...@@ -532,7 +547,7 @@ rw_lock_x_unlock_direct(
lock->lock_word += X_LOCK_DECR; lock->lock_word += X_LOCK_DECR;
ut_ad(!lock->waiters); ut_ad(!rw_lock_get_waiters(lock));
ut_ad(rw_lock_validate(lock)); ut_ad(rw_lock_validate(lock));
#ifdef UNIV_SYNC_PERF_STAT #ifdef UNIV_SYNC_PERF_STAT
......
...@@ -549,7 +549,8 @@ sync_array_find_thread( ...@@ -549,7 +549,8 @@ sync_array_find_thread(
cell = sync_array_get_nth_cell(arr, i); cell = sync_array_get_nth_cell(arr, i);
if (cell->wait_object != NULL if (cell->wait_object != NULL
&& os_thread_eq(cell->thread, thread)) { && os_thread_eq(cell->thread, thread)
&& cell->waiting)) {
return(cell); /* Found */ return(cell); /* Found */
} }
...@@ -887,6 +888,10 @@ sync_arr_wake_threads_if_sema_free(void) ...@@ -887,6 +888,10 @@ sync_arr_wake_threads_if_sema_free(void)
} }
count++; count++;
if (!cell->waiting) {
continue;
}
if (sync_arr_cell_can_wake_up(cell)) { if (sync_arr_cell_can_wake_up(cell)) {
event = sync_cell_get_event(cell); event = sync_cell_get_event(cell);
......
...@@ -209,7 +209,7 @@ rw_lock_create_func( ...@@ -209,7 +209,7 @@ rw_lock_create_func(
#endif /* UNIV_SYNC_ATOMIC */ #endif /* UNIV_SYNC_ATOMIC */
lock->lock_word = X_LOCK_DECR; lock->lock_word = X_LOCK_DECR;
rw_lock_set_waiters(lock, 0); lock->waiters = 0;
lock->writer_thread = -1; lock->writer_thread = -1;
lock->pass = 0; lock->pass = 0;
...@@ -369,7 +369,7 @@ rw_lock_s_lock_spin( ...@@ -369,7 +369,7 @@ rw_lock_s_lock_spin(
/* Set waiters before checking lock_word to ensure wake-up /* Set waiters before checking lock_word to ensure wake-up
signal is sent. This may lead to some unnecessary signals. */ signal is sent. This may lead to some unnecessary signals. */
rw_lock_set_waiters(lock, 1); rw_lock_set_waiters(lock);
if (TRUE == rw_lock_s_lock_low(lock, pass, file_name, line)) { if (TRUE == rw_lock_s_lock_low(lock, pass, file_name, line)) {
sync_array_free_cell(sync_primary_wait_array, index); sync_array_free_cell(sync_primary_wait_array, index);
...@@ -634,7 +634,7 @@ rw_lock_x_lock_func( ...@@ -634,7 +634,7 @@ rw_lock_x_lock_func(
/* Waiters must be set before checking lock_word, to ensure signal /* Waiters must be set before checking lock_word, to ensure signal
is sent. This could lead to a few unnecessary wake-up signals. */ is sent. This could lead to a few unnecessary wake-up signals. */
rw_lock_set_waiters(lock, 1); rw_lock_set_waiters(lock);
if (rw_lock_x_lock_low(lock, pass, file_name, line)) { if (rw_lock_x_lock_low(lock, pass, file_name, line)) {
sync_array_free_cell(sync_primary_wait_array, index); sync_array_free_cell(sync_primary_wait_array, index);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment