Description: Fix crash on Power8 when built with advanced tool chain This was later discovered to also fix a corruption issue on AArch64: https://mariadb.atlassian.net/browse/MDEV-6615 Origin: https://github.com/MariaDB/server/commit/40497577ffd9f85557b15e08ad913f627b2e9530 Bug-Ubuntu: https://bugs.launchpad.net/bugs/1427406 Forwarded: http://bugs.mysql.com/bug.php?id=76135 Author: Sergey Vojtovich Last-Update: 2015-03-30 Index: mysql-5.6/storage/innobase/include/os0sync.h =================================================================== --- mysql-5.6.orig/storage/innobase/include/os0sync.h +++ mysql-5.6/storage/innobase/include/os0sync.h @@ -438,6 +438,9 @@ Returns the old value of *ptr, atomicall # define os_atomic_test_and_set_ulint(ptr, new_val) \ __sync_lock_test_and_set(ptr, new_val) +# define os_atomic_lock_release_byte(ptr) \ + __sync_lock_release(ptr) + #elif defined(HAVE_IB_SOLARIS_ATOMICS) # define HAVE_ATOMIC_BUILTINS @@ -520,6 +523,9 @@ Returns the old value of *ptr, atomicall # define os_atomic_test_and_set_ulint(ptr, new_val) \ atomic_swap_ulong(ptr, new_val) +# define os_atomic_lock_release_byte(ptr) \ + (void) atomic_swap_uchar(ptr, 0) + #elif defined(HAVE_WINDOWS_ATOMICS) # define HAVE_ATOMIC_BUILTINS @@ -644,6 +650,9 @@ clobbered */ # define os_atomic_test_and_set_ulong(ptr, new_val) \ InterlockedExchange(ptr, new_val) +# define os_atomic_lock_release_byte(ptr) \ + (void) InterlockedExchange(ptr, 0) + #else # define IB_ATOMICS_STARTUP_MSG \ "Mutexes and rw_locks use InnoDB's own implementation" Index: mysql-5.6/storage/innobase/include/sync0sync.ic =================================================================== --- mysql-5.6.orig/storage/innobase/include/sync0sync.ic +++ mysql-5.6/storage/innobase/include/sync0sync.ic @@ -113,11 +113,8 @@ mutex_reset_lock_word( ib_mutex_t* mutex) /*!< in: mutex */ { #if defined(HAVE_ATOMIC_BUILTINS) - /* In theory __sync_lock_release should be used to release the lock. - Unfortunately, it does not work properly alone. The workaround is - that more conservative __sync_lock_test_and_set is used instead. */ # if defined(HAVE_ATOMIC_BUILTINS_BYTE) - os_atomic_test_and_set_byte(&mutex->lock_word, 0); + os_atomic_lock_release_byte(&mutex->lock_word); # else os_atomic_test_and_set_ulint(&mutex->lock_word, 0); # endif