Created by Laurynas Biveinis and last modified
Get this branch:
bzr branch lp:~laurynas-biveinis/percona-server/bug1236696
Only Laurynas Biveinis can upload to this branch. If you are Laurynas Biveinis please log in for upload directions.

Branch merges

Related bugs

Related blueprints

Branch information

Recent revisions

476. By Laurynas Biveinis

Fix bug 1240044 (Redundant wakeups in priority
rw_lock_s_unlock_func()) by removing the spurious high-priority S and
X wakeups from priority rw_lock_s_unlock_func().

475. By Laurynas Biveinis

Fix bug 1236696.

The issue is a number of race conditions between successful priority
mutex or RW lock locks that happen after having set the waiters flag
(the last locking attempts before waiting), and unlocks.

If a lock (both priority mutex, or a priority RW lock) is successfully
locked this way, the corresponding waiters flag remains set, although
other waiters for this flag do not necessarily exist. Then on unlock,
the flag being set causes the corresponding event to be set (which may
have no waiters), and prevent lower-priority waiters from waking up,
leaving the lock unlocked but its waiters sleeping.

Fix by making ib_prio_mutex_t::high_priority_waiters,
prio_rw_lock_t::high_priority_x_waiters, and
prio_rw_lock_t::high_priority_s_waiters to be actual waiting thread
count instead of 0/1 flag. The counts are atomically incremented by
1 where the flag used to be set to 1, and atomically decremented if
locking after setting the waiters flag has succeeded or upon wakeup
instead of doing nothing. Remove the flag resets from the unlocking
functions as its job will be done by the waiting threads themselves
upon wake up.

There is no need to adjust the regular waiters flags this way, as
there are no lower priority events that could be missed because of
their value being too large.

Also fix prio_rw_lock_t::high_priority_wait_ex_waiter flag handling.
Since there can be at most one wait_ex waiter, there is no need to use
atomic inc and dec operations, and it is enough to simply reset the
flag on successful lock. Assert that a high priority wait_ex waiter
does not exist before an X unlock.

Also adjust rw_lock_get_waiters() to use || instead of | for checking
for waiters presence as this function should return only 0 or 1.

Branch metadata

Branch format:
Branch format 7
Repository format:
Bazaar repository format 2a (needs bzr 1.16 or later)
Stacked on:
This branch contains Public information 
Everyone can see this information.