• Sergey Vojtovich's avatar
    MDEV-14529 - InnoDB rw-locks: optimize memory barriers · b04f2a0f
    Sergey Vojtovich authored
    Relax memory barrier for lock_word.
    
    rw_lock_lock_word_decr() - used to acquire rw-lock, thus we only need to issue
    ACQUIRE when we succeed locking.
    
    rw_lock_x_lock_func_nowait() - same as above, but used to attempt to acquire
    X-lock.
    
    rw_lock_s_unlock_func() - used to release S-lock, RELEASE is what we need here.
    
    rw_lock_x_unlock_func() - used to release X-lock. Ideally we'd need only RELEASE
    here, but due to mess with waiters (they must be loaded after lock_word is
    stored) we have to issue both ACQUIRE and RELEASE.
    
    rw_lock_sx_unlock_func() - same as above, but used to release SX-lock.
    
    rw_lock_s_lock_spin(), rw_lock_x_lock_func(), rw_lock_sx_lock_func() -
    fetch-and-store to waiters has to issue only ACQUIRE memory barrier, so that
    waiters are stored before lock_word is loaded.
    
    Note that there is violation of RELEASE-ACQUIRE protocol here, because we do
    on lock:
    
      my_atomic_fas32_explicit((int32*) &lock->waiters, 1, MY_MEMORY_ORDER_ACQUIRE);
      my_atomic_load32_explicit(&lock->lock_word, MY_MEMORY_ORDER_RELAXED);
    
    on unlock
    
      my_atomic_add32_explicit(&lock->lock_word, X_LOCK_DECR, MY_MEMORY_ORDER_ACQ_REL);
      my_atomic_load32_explicit((int32*) &lock->waiters, MY_MEMORY_ORDER_RELAXED);
    
    That is we kind of synchronize ACQUIRE on lock_word with ACQUIRE on waiters.
    It was there before this patch. Simple fix may have negative performance impact.
    Proper fix requires refactoring of lock_word.
    b04f2a0f
sync0rw.cc 34.9 KB