mirror of
https://github.com/MariaDB/server.git
synced 2025-10-28 17:15:19 +03:00
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).
This commit is contained in:
@@ -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(
|
|||||||
/* 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(
|
|||||||
/* 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(
|
|||||||
|
|
||||||
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(
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
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(
|
|||||||
#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 @@ lock_loop:
|
|||||||
|
|
||||||
/* 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 @@ lock_loop:
|
|||||||
|
|
||||||
/* 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);
|
||||||
|
|||||||
Reference in New Issue
Block a user