It is not clear why the committed fix for this bug gathers a bit mask all of X waiters.
The original 5.5 code is
if (UNIV_UNLIKELY(rw_lock_get_writer(&btr_search_latch) != RW_LOCK_NOT_LOCKED)
&& trx->has_search_latch) {
/* There is an x-latch request on the adaptive hash index:
release the s-latch to reduce starvation and wait for
BTR_SEA_TIMEOUT rounds before trying to keep it again over
calls from MySQL */
should_release = 0;
for (i = 0; i < btr_search_index_num; i++) {
/* we should check all latches (fix Bug#791030) */
if (UNIV_UNLIKELY(rw_lock_get_writer(btr_search_latch_part[i])
!= RW_LOCK_NOT_LOCKED)) {
should_release |= ((ulint)1 << i);
}
}
if (UNIV_UNLIKELY(should_release)) {
for (i = 0; i < btr_search_index_num; i++) {
/* we should release all s-latches (fix Bug#791030) */
if (trx->has_search_latch & ((ulint)1 << i)) {
rw_lock_s_unlock(btr_search_latch_part[i]);
trx->has_search_latch &= (~((ulint)1 << i));
}
}
Thus, it checks all the latches for the X waiters and collects a bitmask of them. That bitmask is only used if any bit is set, and if yes, the S latches are released for which the current transaction thinks it has the latch for. The individual bit info in the should_release is not used at all. The should_release and trx->has_search_latch bitmasks are not identical.
It can be rewritten as
should_release = false;
for (i = 0; i < btr_search_index_num; i++) {
/* we should check all latches (fix Bug#791030) */
if (UNIV_UNLIKELY(rw_lock_get_writer(btr_search_latch_part[i])
!= RW_LOCK_NOT_LOCKED)) {
should_release = true;
break;
}
}
if (UNIV_UNLIKELY(should_release) { trx_search_latch_release_if_reserved();
It is not clear why the committed fix for this bug gathers a bit mask all of X waiters.
The original 5.5 code is
if (UNIV_UNLIKELY( rw_lock_ get_writer( &btr_search_ latch) != RW_LOCK_NOT_LOCKED) search_ latch) {
&& trx->has_
/* There is an x-latch request on the adaptive hash index:
release the s-latch to reduce starvation and wait for
BTR_SEA_TIMEOUT rounds before trying to keep it again over
calls from MySQL */
rw_lock_ s_unlock( &btr_search_ latch); search_ latch = FALSE;
trx->has_
The current XtraDB 5.5 code is
should_release = 0; index_num; i++) { rw_lock_ get_writer( btr_search_ latch_part[ i]) NOT_LOCKED) ) {
for (i = 0; i < btr_search_
/* we should check all latches (fix Bug#791030) */
if (UNIV_UNLIKELY(
!= RW_LOCK_
should_release |= ((ulint)1 << i);
}
}
if (UNIV_UNLIKELY( should_ release) ) {
for (i = 0; i < btr_search_ index_num; i++) { search_ latch & ((ulint)1 << i)) { lock_s_ unlock( btr_search_ latch_part[ i]); >has_search_ latch &= (~((ulint)1 << i));
/* we should release all s-latches (fix Bug#791030) */
if (trx->has_
rw_
trx-
}
}
Thus, it checks all the latches for the X waiters and collects a bitmask of them. That bitmask is only used if any bit is set, and if yes, the S latches are released for which the current transaction thinks it has the latch for. The individual bit info in the should_release is not used at all. The should_release and trx->has_ search_ latch bitmasks are not identical.
It can be rewritten as
should_release = false; index_num; i++) { rw_lock_ get_writer( btr_search_ latch_part[ i]) NOT_LOCKED) ) {
for (i = 0; i < btr_search_
/* we should check all latches (fix Bug#791030) */
if (UNIV_UNLIKELY(
!= RW_LOCK_
should_release = true;
break;
}
}
if (UNIV_UNLIKELY( should_ release) {
trx_search_ latch_release_ if_reserved( );